Can anybody explain the details? If I create an object using
$var = [PSObject]@{a=1;b=2;c=3}
and then I look for its type using getType()
PowerShell tells me it's of type Hashtable.
When using Get-Member (alias gm
) to inspect the object it's obvious that a hashtable has been created, since it has a keys
and a values
property. So what's the difference to a "normal" hashtable?
Also, what's the advantage of using a PSCustomObject? When creating one using something like this
$var = [PSCustomObject]@{a=1;b=2;c=3}
the only visible difference to me is the different datatype of PSCustomObject. Also instead of keys and value properties, a inspection with gm
shows that now every key has been added as a NoteProperty object.
But what advantages do I have? I'm able to access my values by using its keys, just like in the hashtable. I can store more than simple key-value pairs (key-object pairs for example) in the PSCustomObject, JUST as in the hashtable. So what's the advantage? Are there any important differences?
Say I want to create a folder. If I use a PSObject you can tell it is wrong by looking at it
However the PSCustomObject looks correct
I can then pipe the object
From the
PSObject
documentation:In other words, a
PSObject
is an object that you can add methods and properties to after you've created it.From the "About Hash Tables" documentation:
You can use a
PSObject
like aHashtable
because PowerShell allows you to add properties toPSObjects
, but you shouldn't do this because you'll lose access toHashtable
specific functionality, such as theKeys
andValues
properties. Also, there may be performance costs and additional memory usage.The PowerShell documentation has the following information about
PSCustomObject
:This was unclear to me, but a post on a PowerShell forum from the co-author of a number of PowerShell books seems more clear:
Regarding your code,
@{a=1;b=2;c=3}
is aHashtable
.[PSObject]@{a=1;b=2;c=3}
doesn't convert theHashtable
to aPSObject
or generate an error. The object remains aHashtable
. However,[PSCustomObject]@{a=1;b=2;c=3}
convers theHashtable
into aPSObject
. I wasn't able to find documentation stating why this happens.If you want to convert a
Hashtable
into an object in order to use its keys as property names you can use one of the following lines of code:If you want to convert a number of
Hashtables
into an object where their keys are property names you can use the following code:Finding documentation regarding
NoteProperty
was difficult. In theAdd-Member
documentation, there isn't any-MemberType
that makes sense for adding object properties other thanNoteProperty
. The Windows PowerShell Cookbook (3rd Edition) defined theNoteproperty
Membertype as:One scenario where
[PSCustomObject]
is used instead ofHashTable
is when you need a collection of them. The following is to illustrate the difference in how they are handled:Format-Table
will result in the following for$Hash
:And the following for
$CustomObject
:The same thing happens with
Export-Csv
, thus the reason to use[PSCustomObject]
instead of just plainHashTable
.One advantage I think for PSObject is that you can create custom methods with it.
For example,
You can use this to control the sorting order of the PSObject properties (see PSObject sorting)
I think the biggest difference you'll see is the performance. Have a look at this blog post:
Combining Objects Efficiently – Use a Hash Table to Index a Collection of Objects
The author ran the following code:
His comment regarding the code results is:
Here are some of the other, more-subtle benefits: Custom objects default display in PowerShell 3.0