并非所有属性显示



当我们试图通过管道将数据导出到其他功能时,我们会在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 propertiesOut-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

相关内容

  • 没有找到相关文章

最新更新