Summary: Microsoft Scripting Guy, Ed Wilson, talks about dealing with Windows PowerShell hash tables that contain keywords. Dude!
Hey, Scripting Guy! I have a problem in that I want to create a hash table from an array. This is easy enough to do, but if the array contains keywords, then everything goes pear shaped. Any ideas?
—GP
Hello GP,
Microsoft Scripting Guy, Ed Wilson, is here. Things are certainly becoming exciting around here. The Scripting Wife and I have been busy planning for TechEd North America in New Orleans and TechEd Europe in Madrid. As it turns out, we will have a Scripting Guys booth in both New Orleans and Madrid. In addition, we are sharing our booth with the folks from PowerShell.org; so, that means that Windows PowerShell people like Don Jones will be there. I am also going to be working with the Windows PowerShell team on a couple of instructor lead labs that (to be quite honest) will absolutely knock your socks off —they are that cool. More details to follow.
Creating a hash table that contains keywords
Well GP, I have never actually run across your problem before. This is because I avoid using Windows PowerShell keywords. I refer to the Help topic, about_Language_Keywords, from time to time to refresh my mind when it comes to reserved keywords.
Note As an aside, I do the same thing for automatic variables. For more information, see about_Automatic_Variables in the Script Center.
Here is the easy way to bring up the about_Language_Keywords Help topic:
help -Category helpfile -Name *keyword*
So, this is all on the preventive side of things. To experiment with this, the first thing I do is create an array that contains a few keywords—in addition to other words. I then use the ForEachcommand to add the items in the array to a hash table. This technique is shown here:
PS C:\> $a = "key","keys","property","properties","red","blue","green"
PS C:\> $h = @{}
PS C:\> foreach ($wd in $a) {$h[$wd] = $true}
If I look at the hash table that is contained in the $h variable, I see the following:
PS C:\> $h
Name Value
---- -----
red True
property True
green True
keys True
properties True
blue True
key True
So far, so good. But suppose I want to look at the properties or the keys of my hash table. I try the following:
PS C:\> $h.Keys
True
PS C:\> $h.key
True
PS C:\> $h.property
True
PS C:\> $h.properties
True
So I am wondering what the properties really are for this hash table. I can find out by using the Get-Member command as shown here.
PS C:\> Get-Member -InputObject $h -MemberType Properties
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Count Property int Count {get;}
IsFixedSize Property bool IsFixedSize {get;}
IsReadOnly Property bool IsReadOnly {get;}
IsSynchronized Property bool IsSynchronized {get;}
Keys Property System.Collections.ICollection Keys {get;}
SyncRoot Property System.Object SyncRoot {get;}
Values Property System.Collections.ICollection Values {get;}
There really is a property called Keys, and I really cannot seem to access it. So what do I do?
I imagine that I will take a look at the base Windows PowerShell object. To do this, I use the PSBaseproperty. All Windows PowerShell objects have a base object, but most of the time, it is not necessary to fool with it. Here, however, I suspect that I will be able to get past the keys keys kind of thing. Here is the base object:
PS C:\> $h.psbase
IsReadOnly : False
IsFixedSize : False
IsSynchronized : False
Keys : {red, property, green, keys...}
Values : {True, True, True, True...}
SyncRoot : System.Object
Count : 7
Now, I see there is a Keysproperty on the base object. So I attempt to access it. Here is how I do it:
PS C:\> $h.psbase.keys
red
property
green
keys
properties
blue
key
GP, that is all there is to using PSBase when dealing with hash tables. By the way, I tested this on Windows PowerShell 2.0 and on Windows PowerShell 3.0, so you should be safe to use this technique. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.
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