Powershell: Order of hashtable.Keys is inconsistant between Powershell 7 and Windows Powershell 5

Created on 3 Sep 2020  路  3Comments  路  Source: PowerShell/PowerShell

I understand that when adding entries to an unordered hashtable, the order of the results will be inconsistent with the order the entries were made. But in Powershell 5, the order was consistantly inconsistant. Meaning, whatever order the entries were returned, they would always be returned in that order based on the same input. In Powershell 7, again, we see the consitently inconsistent return of hashtable results - as long as the input and its order is exactly the same each time.

The problem is, the inconsistent order is not the same between PS5 and PS7. Take the following scenario:
I create a hash-table (per the steps to reproduce below), and I want to make a new string by concatenating the keys of the hash-table, in whatever order they are returned. Such as

$hash.Keys -join ""

which should produce "test7test9test3test2test1test4test6test5test8" in Powershell 5.
Now, when I create the same hash-table in PS7, and do the key concatenation, the result is "test7test6test3test9test1test2test4test8test5". The result is always the same over repeated runs in PS5. The result is always the same over repeated runs in PS7. But the results are different between PS5 and PS7.

This came up because we did this type of concatenation to come up with a naming convention, and we could consistently refer to the generated names in PS5. But now when running the same code in PS7, the generated names are different and thus breaking our scripts.

Steps to reproduce

$hash = @{}
$hash.Add("test1", $null)
$hash.Add("test2", $null)
$hash.Add("test3", $null)
$hash.Add("test4", $null)
$hash.Add("test5", $null)
$hash.Add("test6", $null)
$hash.Add("test7", $null)
$hash.Add("test8", $null)
$hash.Add("test9", $null)
$hash.Keys

Expected behavior

test7
test9
test3
test2
test1
test4
test6
test5
test8

Actual behavior

test7
test3
test6
test9
test1
test2
test4
test8
test5

Environment data


Powershell 5

Name                           Value
----                           -----
PSVersion                      5.1.17134.858
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17134.858
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Powershell 7

Name                           Value
----                           -----
PSVersion                      7.0.3
PSEdition                      Core
GitCommitId                    7.0.3
OS                             Microsoft Windows 10.0.17134
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question Resolution-Answered

Most helpful comment

Typically the order will be inconsistent even between different sessions of the same version, in my experience.

Either way, even if the hash sorting algorithm changed for some reason, that's not something PowerShell has any control over. If it changed, that would have happened at the .NET layer.

As ever, if you need an ordered dictionary, use an ordered dictionary type; PowerShell provides the [ordered]@{ ... } syntax for this reason. Regardless of precisely how it surfaces, the order of keys in a standard hashtable can never be guaranteed.

All 3 comments

Typically the order will be inconsistent even between different sessions of the same version, in my experience.

Either way, even if the hash sorting algorithm changed for some reason, that's not something PowerShell has any control over. If it changed, that would have happened at the .NET layer.

As ever, if you need an ordered dictionary, use an ordered dictionary type; PowerShell provides the [ordered]@{ ... } syntax for this reason. Regardless of precisely how it surfaces, the order of keys in a standard hashtable can never be guaranteed.

You could ask in .Net repository. But as @vexx32 explained it is implementation details and you should sort keys if you want predictable results.
We can not fix this in PowerShell Engine.

Sounds good thanks for confirming the behavior is expected and suggesting alternative ways to accomplish more predictable results.

Was this page helpful?
0 / 5 - 0 ratings