Not all properties displayed
When we're trying to export data to other functions via the pipeline, we observe some strange behavior in PowerShell.
Example code:
$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'
In the example above you can see that when the first object only contains 2 properties
, the Out-GridView
CmdLet (and others) only show 2 properties
, even though the second object has 3 properties
. However, when the first object in the array has 3 properties
it does display them all correctly.
Is there a way around this? Because it's not possible to predict up front how many properties
on an object there will be and if the object with the most properties
will be the first one in the array
.
I had the same experience once and created the following reusable 'Union
' function:
# 2021-08-25 Removed Union function
Usage:
$Obj1, $Obj2 | Union | Out-GridView -Title 'Showing all members'
It is also supposed to work with complex objects. Some standard cmdlets output multiple object types at once and if you view them (e.g. Out-GridView
) or dump them in a file (e.g. Export-Csv
) you might miss a lot of properties. Take as another example:
Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosSetting | Union | Export-Csv ".\HPBIOS.csv"
Added 2014-09-19:
Maybe this is already between the lines in the comments $Array | Select * | …
will not resolve the issue but specifically selecting the properties $Array | Select Member1, Member2, Member3 | …
does.
Besides, although in most cases the Union
function will work, there are some exceptions to that as it will only align the first object with the rest.
Consider the following object:
$List = @(
New-Object PSObject -Property @{Id = 2}
New-Object PSObject -Property @{Id = 1}
New-Object PSObject -Property @{Id = 3; Name = "Test"}
)
If you Union
this object everything appears to be fine and if you e.g. ExportTo-CSV
and work with the export .csv
file from then on you will never have any issue.
$List | Union
Id Name
-- ----
2
1
3 Test
Still there is a catch as only the first object is aligned. If you e.g. sort the result on Id
(Sort Id
) or take just the last 2 (Select -Last 2
) entries, the Name
is not listed because the second object doesn’t contain the Name
property:
$List | Union | Sort Id
Id
--
1
2
3
Therefor I have rewritten the Union-Object
(Alias Union
) function`):
Union-Object
# 2021-08-25 Removed Union-Object function
Syntax:
$Array | Union | Out-GridView -Title 'All members correctly displayed'
Update 2021-08-25
Based on az1d helpful feedback on an error caused by equal property names with different casing, I have created a new UnifyProperties
function.
(I will no longer use the name for his)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)
}
Usage:
[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
See also: #13906
Add -UnifyProperties parameter to Select-Object