Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to create an ordered dictionary.
Microsoft Scripting Guy, Ed Wilson, is here. One of the really cool things that was introduced in Windows PowerShell 3.0, is that I can create an ordered dictionary. Basically, an ordered dictionary works like a Windows PowerShell hash table. The difference is that it maintains its order.
Note For a good overview of the ordered dictionary in Windows PowerShell, refer to this Hey, Scripting Guy! Blog post by June Blender: ConvertTo-OrderedDictionary.
Dude, it is frustrating…
One of the most frustrating things in the world is the way that nice, pretty, well-organized Windows PowerShell hash tables randomly seem to become jumbled up. Well, maybe it is not THE most frustrating thing in the world, but it is right up there with cold popcorn at a movie or a soggy sandwich on an airplane.
You don’t get it? Here is an example (a non-sorted hash table, not a soggy sandwich)...
I create a nice hash table, specify the letters in order, and boom! They become jumbled.
PS C:\> $d = @{a=28;b=29;c=30}
PS C:\> $d
Name Value
---- -----
c 30
b 29
a 28
Ordered dictionary objects to the rescue
Note For some of the issues surrounding attempts to sort this type of hash table, see Weekend Scripter: Sorting PowerShell Hash Tables.
If you read this post, you know that it is possible to sort a hash table—it is, well, a bit of extra work. And the whole point of Windows PowerShell is to reduce work, not to make more work.
This is where the ordered dictionary objects come into play. The trick is that it must be done exactly right. Otherwise...well...if it is not done exactly right, it won’t work.
Inside scoop! I will admit that the first time I tried to do this, it did not work. Even the second and third times, it did not work. But then I emailed some people on the Windows PowerShell team, and I was able to figure out what I was doing wrong.
This is how I tried to do it the first time...
I put the [ordered] type accelerator next to the variable I wanted to hold the ordered dictionary. It seemed to make sense.
[ordered]$o = @{a=1;b=2;c=3;d=4}
Here is the output from the command. Notice that it failed, and the error says the ordered attribute can only be specified on a hash literal node. Hmmm, that is about as clear as mud.
The fix is easy
When I was told I had the ordered attribute tag (type accelerator) in the wrong place, I moved it to the right place (both figuratively and literally). Voila! Now it works. Here is the corrected command:
$o = [ordered]@{a=1;b=2;c=3;d=4}
And as appears in the following image, the output is also in the correct order:
I pipe the output to the Get-Member cmdlet, and I can see that it is, in fact, an OrderedDictionary object:
As shown here, I can also retrieve associated key values in the same way that I can with a hash table:
But because it is an OrderedDictionary, I can also directly index into the object (like I can with an array). This is shown here:
$o = [ordered]@{a=1;b=2;c=3;d=4}
PS C:\> $o[1]
2
PS C:\> $o[3]
4
PS C:\> $o[0]
1
If I “accidently” created a hash table and I want to convert it to an ordered dictionary, or if I created an array and I want to convert it to an ordered dictionary, I can use June’s way cool ConvertTo-OrderedDictionary.ps1 script. In fact, it is so cool that I have it in a module in my profile. You can download the script from the Script Center Repository: ConvertTo-OrderedDictionary.
That is all there is to using an ordered dictionary. Join me tomorrow when I will talk about working with local user accounts.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy