2

Is it possible to output an array of Hash Tables that have different keys?

My experiment code is as follows:

$object1 = New-Object psobject -Property @{key1 = "Yep";
key3 = "Sure!"}

$object2 = New-Object psobject -Property @{key2 = "Yep";
key3 = "Sure!"}

$object3 = New-Object psobject -Property @{key1 = "Yep";
key2 = "Yep";
key3 = "Yep"}

Write-Host "Object 1 First"
$OutArray = @()
$OutArray += $object1
$OutArray += $object2

$OutArray

Write-Host "Object 2 First"
$OutArray = @()
$OutArray += $object2
$OutArray += $object1

$OutArray

Write-Host "Object 3 First"
$OutArray = @()
$OutArray += $object3
$OutArray += $object2
$OutArray += $object1

$OutArray

It seems as though they are stored in memory, for when you "Write-Host $OutArray" on either Object 1 or 2 first, you can see the keys and values.

Ultimately, I'm trying to export to CSV a list of ADUser accounts but the ADUser objects in question don't always have all the properties. It seems as though the first element of the array will set what the 'headers' are and then preclude the displaying of other keys, the first element might not have.

Any ideas?

4
  • 1
    If I'm not wrong, you didn't create hash tables, you created PSCustomObjects. I think that's a distinct difference. If you need special attributes in your output you could simply create them with a Select-Object -Property *,'Special Attribute' But usualy even empty attributes will be outputted You might show your "real" code. Commented Mar 10, 2018 at 1:38
  • 2
    @Olaf No, he's running into a fairly standard issue where in an array of objects if you output to Format-Table or Export-Csv it only takes the properties of the first object into consideration, so if any other objects have a property that the first object does not (not that the property has no value, but the first object does not have the property at all) those properties are stripped in the output. Commented Mar 10, 2018 at 1:56
  • 1
    Possible duplicate of Not all properties displayed Commented Mar 10, 2018 at 12:16
  • 1
    Besides the known PowerShell behavior explained Not all properties displayed, it is not a good PowerShell practice to buffer the output in an "$OutArray" array. Instead you should release the objects immediately as they are generated. See: Write Single Records to the Pipeline (SC03) under the Strongly Encouraged Development Guidelines. Commented Mar 10, 2018 at 12:26

1 Answer 1

1

What you can do is add all the missing properties to the first item. First we get all potential properties:

$AllProps = $OutArray |%{$_.PSObject.Properties.Name} |Select -Unique

Then we add the missing ones to the first item in the array.

$AllProps |?{$_ -notin $OutArray[0].PSObject.Properties.Name} |%{Add-Member -InputObject $OutArray[0] -NotepropertyName $_ -NotePropertyValue ''}

Then we can display the array, pipe it to a CSV, or whatever we want and it will behave nicely.

Edit: As Frode F. pointed out, we don't have to add the properties to the first object to make PowerShell output those properties for all objects. We can simply use Select-Object and tell it what properties to display and that will take care of the problem.

$AllProps = $OutArray |%{$_.PSObject.Properties.Name} |Select -Unique
$OutArray | Select $AllProps

You do have to be specific, as using Select * does not behave the same as the above.

Sign up to request clarification or add additional context in comments.

3 Comments

No need to add the missing properties to the objects. Try $array | Select-Object $AllProps | Export-CSV file.csv
@Bill_Stewart No, Select * doesn't work, but specifying each field does. I'll update my answer.
Disregard my comment; I misunderstood the intent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.