Prof. Powershell
Get Your PowerShell Object Properties In Order
PowerShell 3 deploys a new type adapter that will have you seeing hash table output in the order you want them to appear.
- By Jeffery Hicks
- 12/11/2012
In PowerShell 2, a common technique for creating a custom object is to create a hash table of property values and then use the hash table with New-Object:
PS C:\> $hash=@{
>> Name="Jeff"
>> Title="Prof. PowerShell"
>> Version=$host.version
>> OS=$(Get-wmiobject win32_operatingsystem).caption
>> }
>>
PS C:\> new-object psobject -Property $hash
Name Version Title OS
---- ------- ----- --
Jeff 2.0 Prof. PowerShell Microsoft Windows 8 Pro
This works, but notice the output. The property values are not displayed in the order I entered them in the hash table. The problem is that in version 2 hash tables are unordered. There is no predicting what order the values will be displayed. The long way around this problem in version 2 is to create a custom format extension. But that's a lot of work.
In PowerShell 3, we finally have ordered hash tables. You create the hash table the same way, but this time use the [ordered] type adapter:
PS C:\> $hash=[ordered]@{
>> Name="Jeff"
>> Title="Prof. PowerShell"
>> Version=$host.version
>> OS=$(Get-wmiobject win32_operatingsystem).caption
>> }
>>
PS C:\> new-object psobject -prop $hash
Name Title Version OS
---- ----- ------- --
Jeff Prof. PowerShell 3.0 Microsoft Windows 8 Pro
You must put [ordered] right before the hash table, but notice the result. Now the property names are in the same order.
And that's not all. PowerShell 3 also has another type adapter called [pscustomobject]. Now you can create a custom object without having to resort to the New-Object cmdlet. Use the adapter in front of any hash table to turn it into an object:
PS C:\> [pscustomobject]@{
>> Computername = $(Get-wmiobject win32_operatingsystem).csname
>> OS = $(Get-wmiobject win32_operatingsystem).caption
>> Uptime = (get-date) - ([wmiclass]"").ConvertToDateTime((Get-wmiobject win32_operatingsystem).LastBootUpTime)
>> Make = $(get-wmiobject win32_computersystem).model
>> Manufacturer = $(get-wmiobject win32_computersystem).manufacturer
>> MemoryGB = $(Get-WmiObject win32_computersystem).TotalPhysicalMemory/1GB -as [int]
>> Processes = (Get-Process).Count
>> }
>>
Computername : SERENITY
OS : Microsoft Windows 8 Pro
Uptime : 13.08:54:46.1946242
Make : Qosmio X505
Manufacturer : TOSHIBA
Processes : 115
MemoryGB : 8
How easy is that?! If for some reason the hash table isn't ordered, you can combine the type adapters:
[pscustomobject][ordered]@{...
These are great tools that make it even easier to create custom objects from the PowerShell console. In a script, you might still want to use New-Object simply because it is clearer than [pscustomobject]. But I would still use [ordered] when defining the hash table.
So get to PowerShell 3 and get your object properties in order.
About the Author
Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.