Where-Object 没有找到自定义对象的单个实例,但找到了它的多个实例。可能的错误?
Where-Object doesn't find a single instance of a custom object but it finds multiple instances of it. Possible bug?
我正在编写一个脚本,该脚本进行 API 调用并 return 编辑 JSON 结果,并在 Powershell 中作为自定义对象数组进行处理。自定义对象的属性之一是状态,因此对于每个唯一状态,我想获得具有该状态的对象的计数。当我针对某些状态的代码 return 计数为 0 时,我感到很惊讶,因为如果它一开始就不存在,我的脚本就不会搜索该状态。
然后我注意到当有多个对象具有该状态时代码有效,但是当只有一个对象具有该状态时,我的代码将无法使用 Where-Object 找到它。如果我遍历自定义对象数组并执行 if() 语句,它会找到所有状态,包括只有一个对象的状态。
我是不是遗漏了什么或者这是一个错误?我的笔记本电脑是 运行ning PS 5.1,我也在 W2K12 服务器 运行ning PS 4.0 上试过,我得到了同样的结果。
我也能够在下面的代码中模拟这个(删除 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 version:
Major Minor Build Revision
5 1 14393 0
Using Where-Object on the array
Status1
8
Status2
Status3
7
Looping through the array
Status1
8
Status2
1
Status3
7
在第一个示例中(使用 Where-Object
),不能保证管道会产生一个集合 - Status2
它只是 return 一个对象,这就是为什么 Count
没有 return 任何东西。
使用数组子表达式运算符 @()
,您将看到正确的计数:
$uniqueStatuses = ( $testArray.Status | sort | Get-Unique )
foreach ($status in $uniqueStatuses)
{
$status
@($testArray | Select-Object | Where-Object { $_.Status -eq $status }).Count
}
我正在编写一个脚本,该脚本进行 API 调用并 return 编辑 JSON 结果,并在 Powershell 中作为自定义对象数组进行处理。自定义对象的属性之一是状态,因此对于每个唯一状态,我想获得具有该状态的对象的计数。当我针对某些状态的代码 return 计数为 0 时,我感到很惊讶,因为如果它一开始就不存在,我的脚本就不会搜索该状态。
然后我注意到当有多个对象具有该状态时代码有效,但是当只有一个对象具有该状态时,我的代码将无法使用 Where-Object 找到它。如果我遍历自定义对象数组并执行 if() 语句,它会找到所有状态,包括只有一个对象的状态。
我是不是遗漏了什么或者这是一个错误?我的笔记本电脑是 运行ning PS 5.1,我也在 W2K12 服务器 运行ning PS 4.0 上试过,我得到了同样的结果。
我也能够在下面的代码中模拟这个(删除 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 version:
Major Minor Build Revision
5 1 14393 0
Using Where-Object on the array
Status1
8
Status2
Status3
7
Looping through the array
Status1
8
Status2
1
Status3
7
在第一个示例中(使用 Where-Object
),不能保证管道会产生一个集合 - Status2
它只是 return 一个对象,这就是为什么 Count
没有 return 任何东西。
使用数组子表达式运算符 @()
,您将看到正确的计数:
$uniqueStatuses = ( $testArray.Status | sort | Get-Unique )
foreach ($status in $uniqueStatuses)
{
$status
@($testArray | Select-Object | Where-Object { $_.Status -eq $status }).Count
}