在PowerShell中,我有一个需要传递给函数的对象数组。该函数然后循环遍历数组中的所有对象,但似乎它没有正确接受参数值。
采用以下示例,我传递包含两个对象的数组。我希望数组的计数在函数之前和函数内都是2,但是只要它命中函数,计数就是1,而我的输入不是预期的;只发现了最后一个对象。
我在这里遗漏了什么,或者这是PowerShell中的错误?
### I've also tries '[object]', '[array]' and '[array[]]' as the type for '$testArr'.
function Test-PassArrayOfObjects
{
param(
[parameter(Mandatory,ValueFromPipeline)]
[object[]]$testArr
)
Write-Host "In function count: $($testArr.Count)"
$testArr | ForEach-Object { $_ }
}
$test1 = New-Object –TypeName PSObject
$test1 | Add-Member -MemberType NoteProperty -Name Test1 -Value Value1
$test2 = New-Object –TypeName PSObject
$test2 | Add-Member -MemberType NoteProperty -Name Test2 -Value Value2
$testArr = @($test1, $test2)
$testArr.GetType() | Format-Table
Write-Host "Before function count: $($testArr.Count)"
$testArr | Test-PassArrayOfObjects
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Before function count: 2
In function count: 1
Test2
-----
Value2
根据下面的答案,我有这个工作的例子,我已经能够应用到我的现实生活场景中。
function Test-PassArrayOfObjects
{
param(
[parameter(Mandatory,ValueFromPipeline)]
[object]$testArr
)
Process {
Write-Host "In function count: $($testArr.Count)"
$testArr
}
}
$test1 = New-Object –TypeName PSObject
$test1 | Add-Member -MemberType NoteProperty -Name Test1 -Value Value1
$test1 | Add-Member -MemberType NoteProperty -Name Test2 -Value Value2
$test2 = New-Object –TypeName PSObject
$test2 | Add-Member -MemberType NoteProperty -Name Test1 -Value Value1
$test2 | Add-Member -MemberType NoteProperty -Name Test2 -Value Value2
$testArr = @($test1, $test2)
$testArr.GetType() | Format-Table
Write-Host "Before function count: $($testArr.Count)"
$testArr | ForEach-Object { $_ | Test-PassArrayOfObjects }
答案 0 :(得分:3)
通过管道向函数发送输入时,您的函数应包含Process
块:
function Test-PassArrayOfObjects
{
param(
[parameter(Mandatory,ValueFromPipeline)]
[object[]]$testArr
)
Process {
Write-Host "In function count: $($testArr.Count)"
$testArr | ForEach-Object { $_ }
}
}
这是必要的,因为管道处理我相信的集合的方式。它会自动展开它们并一次处理一个项目,因此ForEach-Object
并未将整个集合放入$testArr
变量中。
你经常会看到这样的函数仍然包含ForEach
,如果输入是通过参数发送的,在这种情况下它会被一次性接收。例如:Test-PassArrayOfObjects -TestArr @(1,2,3)
。
您的数组有两个具有不同属性的对象,这进一步加剧了您的问题。这会在输出中产生混淆,因为PowerShell决定如何根据第一个对象格式化输出,并在输出第二个对象时使用相同的格式,但是你不会看到它,因为它不会分享任何相同的属性(我认为这是正在发生的事情..)。
通过将| Format-List
放在$_
上,可以看到两个对象都被处理,这会强制两个输出独立地格式化为列表输出。请注意,当然,这在实际功能场景中并不是一种好的做法。另一种方法是在两个对象Test1
上创建属性名称。然后,您将看到未预期的输出而不使用Format-List
。