未显示所有属性
Not all properties displayed
当我们尝试通过管道将数据导出到其他函数时,我们在 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
时,Out-GridView
CmdLet(和其他)仅显示 2 properties
,即使第二个对象有 3 properties
。但是,当数组中的第一个对象有 3 个 properties
时,它会正确显示它们。
有办法解决这个问题吗?因为无法预先预测一个对象上会有多少 properties
,以及具有最多 properties
的对象是否会成为 array
中的第一个。
我曾经有过同样的经历并创建了以下可重用的“Union
”函数:
# 2021-08-25 Removed Union function
用法:
$Obj1, $Obj2 | <b>Union</b> | Out-GridView -Title 'Showing all members'
它还可以处理复杂的对象。一些标准 cmdlet 一次输出多个对象类型,如果您查看它们(例如 Out-GridView
)或将它们转储到一个文件中(例如 Export-Csv
),您可能会错过很多属性。再举个例子:
Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosSetting | <b>Union</b> | 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
)函数`):
联合对象
# 2021-08-25 Removed Union-Object function
语法:
$Array | Union | Out-GridView -Title 'All members correctly displayed'
更新2021-08-25
基于 az1d 对因 属性 名称大小写不同而导致的错误的有用反馈,我创建了一个新的 UnifyProperties
函数。
(我不会再用他的名字UnionObject
)
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
当我们尝试通过管道将数据导出到其他函数时,我们在 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
时,Out-GridView
CmdLet(和其他)仅显示 2 properties
,即使第二个对象有 3 properties
。但是,当数组中的第一个对象有 3 个 properties
时,它会正确显示它们。
有办法解决这个问题吗?因为无法预先预测一个对象上会有多少 properties
,以及具有最多 properties
的对象是否会成为 array
中的第一个。
我曾经有过同样的经历并创建了以下可重用的“Union
”函数:
# 2021-08-25 Removed Union function
用法:
$Obj1, $Obj2 | <b>Union</b> | Out-GridView -Title 'Showing all members'
它还可以处理复杂的对象。一些标准 cmdlet 一次输出多个对象类型,如果您查看它们(例如 Out-GridView
)或将它们转储到一个文件中(例如 Export-Csv
),您可能会错过很多属性。再举个例子:
Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosSetting | <b>Union</b> | 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
)函数`):
联合对象
# 2021-08-25 Removed Union-Object function
语法:
$Array | Union | Out-GridView -Title 'All members correctly displayed'
更新2021-08-25
基于 az1d 对因 属性 名称大小写不同而导致的错误的有用反馈,我创建了一个新的 UnifyProperties
函数。
(我不会再用他的名字)UnionObject
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