Aggregate objects with different number of properties

I’m not a programmer so please excuse any misused terminology.

I’m trying to build a script listing properties for some user. I use a simple cycle to go over each user and construct a custom object containing the properties, then aggregate it. The issue is that most of these properties can be empty/non-existent and this causes issues on the aggregation part. To illustrate this, I have provided a simple example. Can you please explain to me why is this behavior and how to avoid it?

 $obj1 = New-Object PSObject
 Add-Member -InputObject $obj1 -MemberType NoteProperty -Name "UserPrincipalName" -Value "user"
 Add-Member -InputObject $obj1 -MemberType NoteProperty -Name "Name" -Value "User Name"

 $obj2 = New-Object PSObject
 Add-Member -InputObject $obj2 -MemberType NoteProperty -Name "UserPrincipalName" -Value "user2"

 $arr = @()
 $arr += $obj1
 $arr += $obj2
 $arr

In this case, it is working as expected:

UserPrincipalName                                                                                                Name 
-----------------                                                                                                ----  
user                                                                                                  User Name 
user2                                                                                                                   

However, if I simply change the order of obj1 and obj2, the “Name” property gets stripped:

 $arr = @()
 $arr += $obj2
 $arr += $obj1
 $arr

UserPrincipalName
----------------- 
user2
user  

The only way I can make it work as expected is to populate any empty properties with some value, but this basically doubles the code. There must be a more elegant way?

P.S. formatting is broken, sorry :frowning:

Hello Vasil!

You can use the -ErrorAction parameter to tell the shell what to do when an error occures.
One option is SilentlyContinue, which makes the shell continue if the error is non-terminating.
You could try this:

New-Object PSObject -ErrorAction SilentlyContinue

OR

Add-Member parameters  -ErrorAction SilentlyContinue

I’m not sure it will solve the problem - I’m a beginner in PowerShell too -, but it’s cretainly worth a try.

I’ve just checked something and I think you need to do a hash table for the parameters and add a parameter only if it has a value.

Example:

$params = @{Name               = $name
               MemoryStartupBytes = $MemoryStartupBytes
               Generation         = 2
               NewVHDPath         = $NewVHDPath
               NewVHDSizeBytes    = $VHDSizeBytes
               ComputerName       = $ComputerName
               Path               = $VMFolder}
    
    if ($SwitchName) {$params.Add('SwitchName',$SwitchName)}
    if ($BootDevice) {$params.Add('BootDevice',$BootDevice)}

New-VM @params

In this example, if the SwitchName parameter hasn’t been defined, it won’t be added to the parameters of New-VM and it won’t cause an error.
However, if SwitchName does have a value, it will be added.

When outputting an array of objects, only the properties of the first object is chosen by default.

To force all properties to be output you need to specify them by using select like this:

$arr = @()
$arr += $obj2
$arr += $obj1
$arr | Select Name, UserPrincipalName

Thank you sir, I knew it must be something simple :slight_smile: