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 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)
}

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