ValueFromPipeline行为?

时间:2012-02-17 13:07:04

标签: powershell

我有一个命令Get-Testdata,它从不同的源检索测试数据,并将这些数据存储到PSObject中,并将不同的值作为属性。然后将对象的总数存储为数组,以便于操作,排序,计算等。

我的问题是我希望能够将这些数据呈现为(彩色编码)HTML,我已经为此编写了另一个命令Show-TestResults。输入参数如下所示

[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]
[PSObject[]]$InputObject

更新1

这个函数本身是非常基础的,它只是为ConvertTo-HTML设置一些参数,然后将对象传递给该命令:

$head = "<style>[...]" #styling with javascript etc
$header = "<H1>Test Results</H1>
$title = "Test results"
$InputObject | ConvertTo-HTML -head $head -body $header -title $title | Out-File $Filename

END UPDATE 1

但是,当我尝试使用ValueFromPipeline属性时,使用调用

Get-Testdata [...] | Show-TestResults 

仅显示数组中的第一个对象。但是,如果我改为像

那样调用命令
$td = Get-Testdata [...]
Show-TestResults $td 

按预期显示整个阵列。有人可以解释一下 - 并希望引导我纠正它吗?

4 个答案:

答案 0 :(得分:9)

您可能在结束块中处理数据,而不是处理块。

看一个例子:

function getdata {
    1
    2
    3
    4
}
function show-data {
    param(
        [Parameter(mandatory=$true, ValueFromPipeline=$true)]$InputObject,
        [Parameter(mandatory=$true)]$FileName
    )

    # this is process block that is probably missing in your code
    begin { $objects = @() }
    process { $objects += $InputObject }
    end {
        $head = "<style></style>"
        $header = "<H1>Test Results</H1>"
        $title = "Test results"
        $objects | ConvertTo-HTML -head $head -body $header -title $title | Out-File $Filename
    }
}

getdata | show-data -file d:\temp\test.html

答案 1 :(得分:4)

如果需要高级功能,那么我会采用@stej提出的方式。

否则,当函数同时接受管道和参数输入时,我会考虑这个简单的技术:

function Show-Data
(
    $FileName,
    $InputObject
)
{
    # this is the trick:
    if ($InputObject) { $input = $InputObject }

    # process the input (from pipeline or parameter)
    $input | ConvertTo-HTML > $FileName
}

# pipe data
Get-ChildItem | Show-Data Test1.htm

# pass via parameter
Show-Data Test2.htm (Get-ChildItem)

N.B。在这种情况下,$input是管道输入的自动变量。

答案 2 :(得分:2)

我认为问题在于管道将数组展开为对象流,并一次一个地呈现给您的函数,而不是作为数组。

如果你这样做,它是否有效:

,(Get-Testdata [...]) | Show-TestResults 

答案 3 :(得分:2)

我遇到了同样的问题/问题,我通常解决这个问题的方式如下:

eventRender: function( event, element, view ) {
    if (view.name == "month")
    {
        element.find('div.fc-content').append('<div class="circle"></div>'); 
    }
},

我不认为覆盖 automatic $Input variable是个好主意。

无论如何,我还没有看到问题部分的答案:“有人可以解释一下吗?
我想它与Strongly Encouraged Development Guidelines有关,它说明了:

  

支持ProcessRecord方法
  要接受管道中前一个cmdlet的所有记录,   您的cmdlet必须实现ProcessRecord方法。视窗   PowerShell多次调用此方法,每次记录一次   发送到您的cmdlet。

我认为ProcessRecord方法是一种 C#方法,我认为Function Show-Data { param( [Parameter(mandatory=$true, ValueFromPipeline=$true)]$InputObject, [Parameter(mandatory=$true)]$FileName ) $PipeLine = $Input | ForEach {$_}; If ($PipeLine) {$InputObject = $PipeLine} ... 块会调用该方法,如同stej的解决方案一样。但是,这并不能解释为什么这对process数组这种方式起作用,而不是例如系统对象,如:

PSCustomObject

甚至:

Get-psdrive | Show-Data