[PSCustomObject] Need not apply;How PowerShell 2.0 handles objects

Today at a client I had to export some Exchange Information from a one of their Exchange boxes. A simple task, but I kept experiencing some strange issues when I would run my script in PowerShell on the Exchange servers.

The only data I needed was RecipientType, LastLoggedOn and some other similar info, which is also easy to get. It needed to be extracted from Exchange and made ready for assimilation into a larger spreadsheet, so exporting as a Custom Object of some form would be the way to go.

I quickly came up which this script, which should have been more than up to the task. However, the output was very bizarre.

$Array = New-Object -TypeName System.Collections.ArrayList

Function Get-MarkInfo {
   ForEach ($user in $users){
      $mbx = Get-Mailbox $user
      $mbxstat = Get-MailboxStatistics $user
      [PSCustomObject]$obj=@{Name=$user;RecipientType=$mbx.RecipientType;LastLoggedOnUserAccount=$mbxstat.LastLoggedOnUserAccount;LastLogOffTime=$mbxstat.LastLogOffTime;LastLogonTime=$mbxstat.LastLogonTime}
      $Array.Add($obj) | Out-Null
   }
   $Array | export-csv C:\temp\EmailExport.Csv
}

This shouldn’t export these sorts of things

PSObjectWeirdness
Oh no…why is my glorious [PSCustomObject] master race appearing as a hash table? No one asked for key:value pairs!

A hashtable? I never ordered a hashtable!  The CSV output was even worse

PSObjectWeirdness01
No properties? This is what happens when you export a hashtable and don’t enumerate

This was very puzzling. I tried everything under the sun to try and determine why my beautiful little PSCustomObject was coming out as an ugly hashtable. Surely there is an explanation somewhere!  I tried adding Format-Table commands everywhere you could think of, and sorts of craziness with using accelerators to try and force my PSCustomObject to be treated with the respect it deserves.

I ended up digging through old blogposts about ‘Whats New In PowerShell v2’ and v3, when finally I stumbled on these posts:
http://stackoverflow.com/questions/14967920/powershell-3-pscustomobject-displays-in-stupid-mode-via-a-variable
http://www.jonathanmedd.net/2011/09/powershell-v3-creating-objects-with-pscustomobject-its-fast.html

[PSCustomObject] casting is a new feature in PowerShell version 3.0!

A quick check…

PSObjectWeirdness02
There It was, right in front of me

I’d been workign on a 2.0 version server all along! 😦

I did some googling to try to refresh myself on the old way to do it, and even posted on PowerShell.org.

http://blogs.technet.com/b/heyscriptingguy/archive/2011/05/19/create-custom-objects-in-your-powershell-script.aspx

MikeFRobbins( http://mikefrobbins.com/, https://twitter.com/mikefrobbins) chimed in with a text-book perfect solution to my issue.
So, I present to any of you who ever run into this same issue, the PowerShell 2.0 approach to creating and exporting a custom object.

$Array = New-Object -TypeName System.Collections.ArrayList

Function Get-MarkInfo {
   ForEach ($user in $users){
      $mbx = Get-Mailbox $user
      $mbxstat = Get-MailboxStatistics $user

      $ObjectProperties = @{
         Name = $user
         RecipientType=$mbx.RecipientType
         LastLoggedOnUserAccount=$mbxstat.LastLoggedOnUserAccount
         LastLogOffTime=$mbxstat.LastLogOffTime
         LastLogonTime=$mbxstat.LastLogonTime
         }

      $obj = New-Object PSObject -Property $ObjectProperties
      $obj | ft
      $Array.Add($obj) | Out-Null
      }
   $Array | ft
   }
Advertisements

2 thoughts on “[PSCustomObject] Need not apply;How PowerShell 2.0 handles objects

  1. ramblingcookiemonster September 12, 2014 / 12:49 pm

    Good stuff! Big fan of [PSCustomObject], but yeah, PowerShell 3 language feature only.

    One difference that has bitten me a few times is that when using the PowerShell 2 method, properties will not be in consistent order. Not always important, and not everyone cares, but I occasionally need a specific order of properties to display.

    #Unordered. I Get Third, First, Second.
    New-Object -TypeName PSObject -Property @{First=1;Second=2;Third=3}

    #Ordered, but… Now I need to make sure I change the select list if I make a change
    New-Object -TypeName PSObject -Property @{First=1;Second=2;Third=3} | Select First, Second, Third

    #Ordered, no worries, unless we run on PS2!
    [pscustomobject]@{First=1;Second=2;Third=3}

    • FoxDeploy September 12, 2014 / 1:11 pm

      Wow, I never thought about picking the properties out of order like that with a Select statement. Great addition, CookieMonster!

Have a code issue? Share your code by going to Gist.github.com and pasting your code there, then post the link here!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s