[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!

Leave a Reply

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