Change order of columns in the object

Powershell V3 added a type accelerator for [PSCustomObject] that creates objects using an ordered hash table, so the properties stay in the order they're declared:

[PSCustomObject] @{
  Computer=$computer.hostname
  App=$app.appname
  Installed=$installed
}

The problem is that you're adding the properties using a hashtable, and hashtables don't preserve order. You can do one of two things:

1. Add the properties in a manner that will set the order (the last line is to output the object to the pipeline):

$obj = New-Object PSObject
$obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $computer.hostname
$obj | Add-Member -MemberType NoteProperty -Name App -Value $app.appname
$obj | Add-Member -MemberType NoteProperty -Name Installed -Value $installed
$obj

2. Determine the order at the time you output the object to the pipeline using Select-Object:

New-Object PSObject -Property @{
  Computer=$computer.hostname
  App=$app.appname
  Installed=$installed
} | select Computer,App,Installed

Which one is preferable depends on how much you'll be working with the object. If, as your question implies, you're only using the PSObject in order to display the information in tabular format, the second method is quicker. If you're going to output the object multiple times in different parts of the script, the first method allows you to simply output it as $obj rather than having to pipe to select every time.

Note also that the second method can be split up like this if you don't want to output the object immediately after populating it:

$obj = New-Object PSObject -Property @{
   Computer=$computer.hostname
    App=$app.appname
    Installed=$installed
} 

[...do other stuff...]

$obj | select Computer,App,Installed

If you want to ensure the output of an object occurs in a certain order i.e. formatted a certain way then use PowerShell's formatting commands.

$obj = [pscustomobject]@{Computer=$computer.hostname;App=$app.appname;Installed=$installed} 
$obj | Format-Table Computer,App,Installed

What's more you can better control the output e.g.:

$obj | Format-Table Computer,App,Installed -AutoSize

Or control field width & alignment:

$obj | Format-Table @{label='Computer';expression={$_.Computer};width=20;alignment='right'},App,Installed

Frankly I think it is a better practice to use the formatting commands to get the output order you want rather than to rely upon the order in which the properties are created.

Tags:

Powershell