Where-Object没有找到自定义对象的单个实例,但它找到了它的多个实例。可能的错误?

时间:2016-08-12 15:58:55

标签: json powershell pscustomobject

我正在编写一个进行API调用的脚本,并返回一个JSON结果,并在Powershell中作为自定义对象数组处理。自定义对象的一个​​属性是Status,因此对于每个唯一状态,我想获得具有该状态的对象的计数。当我的某些状态的代码返回0时,我感到很惊讶,因为如果它开始时不存在,我的脚本将不会搜索该状态。

然后我注意到当有多个具有状态的对象时代码工作但是当只有一个具有该状态的对象时,我的代码将无法使用Where-Object找到它。如果我遍历自定义对象数组并执行if()语句,它会查找所有状态,包括只有一个对象的状态。

我在这里遗漏了什么或这是一个错误吗?我的笔记本电脑正在运行PS 5.1,我也在运行PS 4.0的W2K12服务器上尝试过它,我得到同样的东西。

我也能够在下面的代码中模拟这个(删除API和JSON部分):

$testArray = @()
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name1' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name2' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status2' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name3' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject

$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name4' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name5' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name6' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject

$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name7' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name8' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name9' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject

$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name10' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject

$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name11' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name12' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name13' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force
$testArray += $testObject

$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name14' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name15' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject
$testObject = New-Object -TypeName PSObject
$testObject | Add-Member -type NoteProperty -name Name -value 'Name16' -Force
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force
$testArray += $testObject


Write-Host "`n`nPowerShell version:"
$PSVersionTable.PSVersion


Write-Host "`n`nUsing Where-Object on the array"
$uniqueStatuses = ( $testArray.Status | sort | Get-Unique )
foreach ($status in $uniqueStatuses)
{
    $status
    ($testArray | Select-Object | Where-Object { $_.Status -eq $status }).Count

}


Write-Host "`n`nLooping through the array"
foreach ($status in $uniqueStatuses)
{
    $status
    [int]$count = 0
    foreach ($object in $testArray)
    {
        if ($object.Status -eq $status)
        {
            $count++
        }   
    }
    $count
}

在上面的示例代码中,状态Status2仅出现在其中一个自定义对象中,而Where-Object由于某种原因找不到它,但是使用foreach确实如此。

当我运行上面的代码时,我得到:

  

PowerShell版本:

     

主要次要构建修订

           

5 1 14393 0

     

在数组上使用Where-Object

     

状态1

     

8

     

状态2

     

STATUS3

     

7

     

循环遍历数组

     

状态1

     

8

     

状态2

     

1

     

STATUS3

     

7

1 个答案:

答案 0 :(得分:4)

在第一个示例中(使用Where-Object),无法保证管道导致集合 - 使用Status2它只返回单个对象,这就是为什么{{1没有任何回报。

使用数组子表达式运算符Count,您将看到正确的计数:

@()