Creating Custom Objects in PowerShell: v3.0 Enhancements

We’re at the end of our multi-part series on creating custom objects in PowerShell! In part one, I discussed the basics of creating custom objects in PowerShell to meet your needs; however, in this version, we lost the original object. In part two, I showed you how to modify and create the custom object while retaining the original. In part three, we learned how to create a custom object from scratch.
Everything I’ve demonstrated up to now is intended for PowerShell 2.0. My examples should also work in the upcoming PowerShell 3.0, but v3 offers some terrific enhancements. Today, I’ll go deeper and include the enhancements found in PowerShell 3.0.

First, instead of using New-Object and passing a hash table of property values, we can easily create an object with the [pscustomobject] type accelerator.

​PS C:\> $obj=[pscustomobject]@{
>> Name="Jeff Hicks"
>> Title="PowerShell Pro"
>> Help="http://bit.ly/AskJeffHicks"
>> Blog="http://jdhitsolutions.com/blog"
>> }
>>

 
I’m still creating a hash table, but in front I’m using the type accelerator. The end result is a custom object.

​PS C:\> $obj | format-list
Name  : Jeff Hicks
Title : PowerShell Pro
Help  : http://bit.ly/AskJeffHicks
Blog  : http://jdhitsolutions.com/blog

 
But it gets better. If you recall from a previous article, there was a subtle issue when using hash tables for property values: you couldn’t control the order. That is still true in PowerShell 3.0. Here’s a simple hash table.

​$drivec=Get-WmiObject win32_logicaldisk -filter "deviceid='C:'"
$hash=@{
Computername=$env:computername
ProcCount=(Get-Process).Count
OS=(Get-WmiObject Win32_operatingsystem).Caption
C_Size=$drivec.size
C_Free=$drivec.freespace
}

 
When I write it to the pipeline as a custom object I get this:

​PS C:\> [pscustomobject]$hash
Computername : CLIENT8
C_Free       : 9823666176
ProcCount    : 87
OS           : Microsoft Windows 8 Pro
C_Size       : 26474442752


Not easy to read and not what I want. But now, we can use another new attribute called [ordered] when defining the hash table.

​$hash=[ordered]@{
Computername=$env:computername
ProcCount=(Get-Process).Count
OS=(Get-WmiObject Win32_operatingsystem).Caption
C_Size=$drivec.size
C_Free=$drivec.freespace
}

 
Now, the table order is maintained both as a hash table and when turned into an object.

​PS C:\> $hash
Name                           Value
----                           -----
Computername                   CLIENT8
ProcCount                      87
OS                             Microsoft Windows 8 Pro
C_Size                         26474442752
C_Free                         9823666176
PS C:\> [pscustomobject]$hash
Computername : CLIENT8
ProcCount    : 87
OS           : Microsoft Windows 8 Pro
C_Size       : 26474442752
C_Free       : 9823666176

 
I love this. Now it is even easier to create rich objects that can live in the pipeline without complicated Select-Object statements or formatting extension files.

​Get-content computers.txt | foreach {
#get some data
$os=get-wmiobject Win32_operatingsystem -ComputerName $_
$process=Get-WmiObject win32_process -ComputerName $_
$psversion=invoke-command {$psversiontable.psversion -as [string]} -ComputerName $_
#build an ordered hash table
$hash=[ordered]@{
Computername=$os.csname
OS=$os.caption
OSArchitecture=$os.osarchitecture
ProcessCount=$process.count
PSVersion=$psversion
}
#write the object to the pipeline
[pscustomobject]$hash
}

 
The end result is a collection of objects that I can use with other PowerShell commands.

​Computername   : CLIENT8
OS             : Microsoft Windows 8 Pro
OSArchitecture : 64-bit
ProcessCount   : 88
PSVersion      : 3.0
Computername   : COREDC01
OS             : Microsoft Windows Server 2008 R2 Standard
OSArchitecture : 64-bit
ProcessCount   : 39
PSVersion      : 2.0
Computername   : QUARK
OS             : Microsoft Windows 8 Release Preview
OSArchitecture : 32-bit
ProcessCount   : 41
PSVersion      : 3.0

 
It’s important to remember, especially with regards to PowerShell 3.0, is to make sure you know how to use hash tables. I suspect they will play an even bigger role in your PowerShell work.
Once again, as we’ve seen here and throughout this series, PowerShell is all about the objects. There are a variety of ways to create and modify them. You’ll also most likely see examples of all these techniques in scripts you find on the Internet. But now, I trust you are eager to put your new found knowledge to work. If you run into issues or have questions, feel free to post in the Ask Don and Jeff forum at PowerShell.com.