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?

  • 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. – Olaf Mar 10 '18 at 01: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. – TheMadTechnician Mar 10 '18 at 01:56
  • 1
    Possible duplicate of [Not all properties displayed](https://stackoverflow.com/questions/44428189/not-all-properties-displayed) – iRon Mar 10 '18 at 12:16
  • 1
    Besides the known PowerShell behavior explained [Not all properties displayed](https://stackoverflow.com/questions/44428189/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](https://msdn.microsoft.com/en-us/library/dd878270(v=vs.85).aspx). – iRon Mar 10 '18 at 12:26

1 Answers1

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.

TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56