Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive

We interrupt our normally scheduled blog for this Public Service Announcement:

Do you use HashTable in your scripts? Have you ever enumerated through the HashTables Keys or checked the HashTable’s Count property? If you have, then you may be the unknowing victim of property hijacking!

Insert Dramatic Music: dum dum dum dum dummmm!

Note: This article only applies to PowerShell V3 and up.

You V2 people are safe. Or are you? Why are you still using V2?! Yeah, I know. The company doesn’t want to upgrade their computers… yada yada yada!


Background Story

Now, this is a story all about how I got property hijacked one day:

I was chillin’ out maxin’ relaxin’ all cool

And all scriptin’ outside of the school

When a couple of bugs who were up to no good

Started making trouble in my neighborhood

I got one little error and my script got scared

Script said “I’m not movin’ till you figure out the bug and error!”

After kickin’ up my debugger in PowerShell Studio, I found the error only occurred when certain values were placed into my HashTable. I found out that the HashTable’s property value was hijacked!


Recreating the Incident

Let’s go over an example that recreates the issue.


Define a HashTable

First, I start off with a simple HashTable:

$hashTable = @{
    'Key1' = 'Value1'
    'Key2' = 'Value2'
    'Key3' = 'Value3'
    'Key4' = 'Value4'
    'Key5' = 'Value5'


Nothing special here. I have some simple key-value pairs.


Accessing Key-Value Pairs as Properties

One of the features introduced in PowerShell V3 is the ability to access the key-value pair via a property:


This line produces the following output:



This seems all fine and dandy. It is a nice shortcut for:



Next, for demonstration purposes I’m going to display the key-value count and the key names of the HashTable:

'------- Beginning Keys -------'
"Count: $($hashTable.Count)"
foreach ($name in $hashTable.Keys)



------- Beginning Keys -------
Count: 5


Key Names That Match Property Names

Now let’s add some new key-value pairs:

$hashTable.Add('Count', 'The Count property was hijacked!')
$hashTable.Add('Keys', 'The Keys property was hijacked!')


Note that the HashTable now has key-value pairs that share the same name as the HashTable’s properties.


Next, let’s display the HashTable’s Count and Keys property values again:

"`r`n------- After Matching Keys -------"
"Count: $($hashTable.Count)"
foreach ($name in $hashTable.Keys)



------- After Matching Keys -------
Count: The Count property was hijacked!
The Keys property was hijacked!


As you can see the HashTable’s properties were hijacked and this is not just limited to HashTables! Use XML or Dictionaries object? Those can be hijacked too!

Property hijacking can cause errors that are hard to find in scripts. Everything might seem fine when you test it, but it breaks in the case where one of the key names matches the property name of the parent object.


How do I access the original property?

The work around I used to avoid this issue, was to use the Select-Object cmdlet:

Select-Object -ExpandProperty Count -InputObject $hashTable


Now the Count property is correctly displayed:



Beware of Note Properties?

Note properties can also hijack the object’s original properties, but only if you use the Force parameter. You can try this:

Add-Member -NotePropertyName Count -NotePropertyValue 'What? Et tu, Note Property?!' -InputObject $hashTable –Force


The Count property will now display:

What? Et tu, Note Property?!


Warning: If you use the Force parameter, the previous Select-Object line will return the note property value and not the original property value.


Lessons Learned

The HashTable key as a property is a time saver for the console but as I demonstrated above, it can have unintended consequences. Such as in the case where you need to access the properties of the original Keys and Count properties of the HashTable.


And remember

This issue isn’t limited to HashTables; XML and Dictionaries objects are also affected, along with any object with a note property forcibly overriding an object property.

And now you know! And knowing is half the battle!
– G.I. Joe


Related Links

Download the Sample Script




If you have questions about our products, please post in our support forum.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Former and Future Customers - Questions forum.
Copyright © 2021 SAPIEN Technologies, Inc.