在Mac上使用PowerShell Core 6.1。看来,将数组传递给ForEach-Object会修改或包装每个元素,以便-is运算符将其全部视为PSCustomObjects。
让我演示一下:
设置一个由四个不同类型的项组成的数组(使用JSON,因为在我的实际用例中数据就是从那里来的):
$a = '[4, "Hi", {}, true]' | ConvertFrom-Json
按索引迭代列表,并确定哪些是PSCustomObjects:
0..3 | ForEach-Object {
$v = $a[$_]
$t = $v.GetType().FullName
$is = $v -is [PSCustomObject]
"$t - $is"
}
(对我而言)输出正是我所期望的:
System.Int64 - False
System.String - False
System.Management.Automation.PSCustomObject - True
System.Boolean - False
但是如果我只是将数组通过管道传递给ForEach-Object:
$a | ForEach-Object {
$v = $_
$t = $v.GetType().FullName
$is = $v -is [PSCustomObject]
"$t - $is"
}
现在输出声称这四个都是PSCustomObjects
System.Int64 - True
System.String - True
System.Management.Automation.PSCustomObject - True
System.Boolean - True
有人可以解释这里发生了什么吗?
答案 0 :(得分:1)
PetSerAl,就像他经常做的那样,在评论中提供了关键的指针:
将对象管道输送到ForEach-Object
会将它们包装在[psobject]
实例中,这将导致-is [pscustomobject]
/ -is [psobject]
返回<{> 1 输入对象,因为-令人困惑-$True
与[pscustomobject]
相同:它们都是[psobject]
的类型加速器-违反了人们的期望,{ {1}}不是[System.Management.Automation.PSObject]
的缩写。
因此,测试输入对象是否为[pscustomobject]
而不是[System.Management.Automation.PSCustomObject]
的实例:
[System.Management.Automation.PSCustomObject]
请注意,如果您使用[pscustomobject]
循环,即使$a | ForEach-Object {
$_ -is [System.Management.Automation.PSCustomObject]
}
也可以使用,因为要枚举的对象然后 not 包裹在额外的foreach
实例:
-is [pscustomobject]
之所以可行,是因为即使在技术上,甚至善意的[psobject]
也是幕后的foreach ($element in $a) {
$element -is [pscustomobject]
}
。