当我们试图通过管道将数据导出到其他功能时,我们会在PowerShell中观察到一些奇怪的行为。
示例代码:
$Array = @()
$Obj1 = [PSCustomObject]@{
Member1 = 'First'
Member2 = 'Second'
}
$Obj2 = [PSCustomObject]@{
Member1 = 'First'
Member2 = 'Second'
Member3 = 'Third'
}
$Array = $Obj1, $Obj2
$Array | Out-GridView -Title 'Not showing Member3'
$Array = $Obj2, $Obj1
$Array | Out-GridView -Title 'All members correctly displayed'
在上面的示例中,您可以看到,当第一个对象仅包含2个 properties
时,即使第二个对象具有3 properties
, Out-GridView
cmdlet(和其他(也仅显示2个 properties
。但是,当数组中的第一个对象具有3 properties
时,它确实正确显示它们。
有办法解决吗?因为不可能预测对象上会有多少个properties
,并且如果properties
最多的对象将是array
中的第一个。
我曾经有相同的经历,并创建了以下可重复使用的' Union
'函数:
# 2021-08-25 Removed Union function
用法:
$Obj1, $Obj2 | Union | Out-GridView -Title 'Showing all members'
它也应该与复杂的对象一起使用。某些标准CMDLET一次一次输出多种对象类型,如果您查看它们(例如Out-GridView
(或将它们转储到文件中(例如Export-Csv
(,则可能会错过很多属性。以另一个例子为例:
Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosSetting | Union | Export-Csv ".HPBIOS.csv"
添加2014-09-19:
也许这已经在注释$Array | Select * | …
中的行之间无法解决问题,但专门选择属性$Array | Select Member1, Member2, Member3 | …
也可以。
此外,尽管在大多数情况下,Union
函数将起作用,但有一些例外,因为它只会使 first 对象与其余对象保持一致。考虑以下对象:
$List = @(
New-Object PSObject -Property @{Id = 2}
New-Object PSObject -Property @{Id = 1}
New-Object PSObject -Property @{Id = 3; Name = "Test"}
)
如果您Union
此对象似乎一切都很好,并且例如 ExportTo-CSV
并使用export .csv
文件,从那时起,您将永远不会有任何问题。
$List | Union
Id Name
-- ----
2
1
3 Test
仍然有一个捕获量,因为只有第一个对象是对齐的。如果您例如对Id
(Sort Id
(上的结果排序或仅进行最后2个(Select -Last 2
(条目,Name
未列出,因为第二个对象不包含Name
属性:
$List | Union | Sort Id
Id
--
1
2
3
因此,我重写了Union-Object
(别名Union
(函数`(:
Union-Object
# 2021-08-25 Removed Union-Object function
语法:
$Array | Union | Out-GridView -Title 'All members correctly displayed'
更新2021-08-25
基于 az1d 有用的反馈,内容是由具有不同壳体的属性名称引起的错误,我创建了一个新的UnifyProperties
功能。
(我将不再使用名称UnionObject
for HIS(
function UnifyProperties {
$Names = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
$InputCollected = @($Input)
$InputCollected.ForEach({
foreach ($Name in $_.psobject.Properties.Name) { $Null = $Names.Add($Name) }
})
$inputCollected | Select-Object @($Names)
}
用法:
[pscustomobject] @{ one = 1; two = 2; three = 3 },
[pscustomobject] @{ ONE = 10; THREE = 30; FOUR = 4 } |
UnifyProperties
one two three FOUR
--- --- ----- ----
1 2 3
10 30 4
另请参见: #13906
add -unifyproperties参数到select -object