Aggregate objects with different number of properties

This topic contains 4 replies, has 3 voices, and was last updated by  Vasil Michev 3 years, 10 months ago.

  • Author
  • #16768

    Vasil Michev

    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

    In this case, it is working as expected:

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

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

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

    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 🙁

  • #16770

    Istvan Szarka

    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
    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.

  • #16771

    Istvan Szarka

    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.


    $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.

  • #16781

    Simon Wåhlin

    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
  • #16783

    Vasil Michev

    Thank you sir, I knew it must be something simple 🙂

You must be logged in to reply to this topic.