在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
谁能解释这是怎么回事?
最佳答案
PetSerAl经常在评论中提供关键指针:
管道对象到ForEach-Object
将它们包装在[psobject]
实例中(反射(reflect)在$_
/ $PSItem
中),这导致-is [pscustomobject]
/ -is [psobject]
返回任何输入对象的$True
,因为-令人困惑-[pscustomobject]
与[psobject]
相同: [System.Management.Automation.PSObject]
的加速器-与人们期望的相反,[pscustomobject]
不只是[System.Management.Automation.PSCustomObject]
的缩写。
因此,将输入对象测试为[System.Management.Automation.PSCustomObject]
的实例而不是[pscustomobject]
的实例:
$a | ForEach-Object {
$_ -is [System.Management.Automation.PSCustomObject]
}
请注意,如果您使用
foreach
循环,即使-is [pscustomobject]
也可以使用,因为被枚举的对象不会包装在额外的[psobject]
实例中:foreach ($element in $a) {
$element -is [pscustomobject]
}
这行得通,因为从技术上说,即使是真正的
[System.Management.Automation.PSCustomObject]
在技术上也是幕后的[System.Management.Automation.PSObject]
。
关于powershell - 在ForEach-Object中使用PowerShell -is运算符时始终匹配PSCustomObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53268394/