PowerShell: Property Hijacking!
- Details
- Written by David Corrales
- Last Updated: 30 August 2019
- Created: 29 April 2019
- Hits: 6637
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:
$hashTable.Key1
|
This line produces the following output:
Value1
This seems all fine and dandy. It is a nice shortcut for:
$hashTable['Key1'] |
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)" 'Keys:' foreach ($name in $hashTable.Keys) { $name } |
Output:
------- Beginning Keys ------- Count: 5 Keys: Key5 Key3 Key1 Key4 Key2
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)" 'Keys:' foreach ($name in $hashTable.Keys) { $name } |
Output:
------- After Matching Keys ------- Count: The Count property was hijacked! Keys: 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:
7
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
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.