Function PowerShell函数不接受对象数组

Function PowerShell函数不接受对象数组,function,powershell,parameters,Function,Powershell,Parameters,在PowerShell中,我有一个需要传递给函数的对象数组。然后,函数将循环遍历数组中的所有对象,但它似乎没有正确接受参数值 以下面的示例为例,我传递了一个包含两个对象的数组。我希望数组的计数在函数之前和函数内部都是2,但一旦它命中函数,计数就为1,并且我的输入与预期不符;只发现最后一个对象 我是在这里遗漏了什么,还是这是PowerShell中的一个bug 示例代码 示例代码的输出 工作装置 根据下面的答案,我有一个工作示例,我已经能够将其应用到我的真实生活场景中 function Test-P

在PowerShell中,我有一个需要传递给函数的对象数组。然后,函数将循环遍历数组中的所有对象,但它似乎没有正确接受参数值

以下面的示例为例,我传递了一个包含两个对象的数组。我希望数组的计数在函数之前和函数内部都是2,但一旦它命中函数,计数就为1,并且我的输入与预期不符;只发现最后一个对象

我是在这里遗漏了什么,还是这是PowerShell中的一个bug

示例代码 示例代码的输出 工作装置 根据下面的答案,我有一个工作示例,我已经能够将其应用到我的真实生活场景中

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 }

通过管道向函数发送输入时,函数应包括
进程
块:

function Test-PassArrayOfObjects
{
    param(
        [parameter(Mandatory,ValueFromPipeline)]
        [object[]]$testArr
    )
    Process {
        Write-Host "In function count: $($testArr.Count)"
        $testArr | ForEach-Object { $_ }
    }
}
这是必要的,因为我相信管道处理集合的方式。它会自动展开它们并一次处理一个项目,因此您的
ForEach对象
不会在
$testArr
变量中获取整个集合


您经常看到这样的函数仍然包含一个
ForEach
,但是,如果输入是通过一个参数发送的,那么在这种情况下它会一次全部接收到。例如:
testpassarrayofoobjects-TestArr@(1,2,3)

数组有两个具有不同属性的对象,这一事实进一步加剧了您的问题。这会在输出中造成混乱,因为PowerShell决定如何基于第一个对象格式化输出,并在输出第二个对象时使用相同的格式,但是您看不到它,因为它不共享任何相同的属性(我认为这就是正在发生的情况)


您可以看到,通过将
|Format List
放在
$\ucode>上,这会强制将两个输出单独格式化为列表输出,从而处理这两个对象。请注意,这当然不是实际功能场景中的良好实践。另一种方法是在两个对象上设置属性名
Test1
。然后,您将看到您可能期望的输出,而无需使用
格式列表

非常感谢您的快速回复。我刚刚完全了解了你的建议。实际上,所有对象都包含相同的属性,所以这不是问题,但我正在做一些更复杂的处理,因此简单地添加
进程
块并不能解决我的问题。然而,您的解释让我将单个对象传递给函数,现在我可以根据需要格式化输出。“您经常看到这样的函数仍然包含ForEach,以防输入通过参数发送,而在这种情况下,它会一次接收到”我觉得这很困惑。最佳做法是什么?还被param类型是否应声明为数组所迷惑。
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 }
function Test-PassArrayOfObjects
{
    param(
        [parameter(Mandatory,ValueFromPipeline)]
        [object[]]$testArr
    )
    Process {
        Write-Host "In function count: $($testArr.Count)"
        $testArr | ForEach-Object { $_ }
    }
}