Prof. Powershell

The PowerShell Way To Dissect Arrays, Hash Tables

This week's tips will have you peeking into data in arrays and hash tables in no time flat.

In Windows PowerShell, you most likely have used arrays and hash tables. The latter is simply a different kind of an array called an associative array. When using arrays, you may have a requirement to see if an item already exists or not in the array or hash table. Perhaps you want to do something with it or add it to the array or hash table if it doesn't exist. Here a few techniques you can try.

First, let's create a simple array:

PS C:\> $arr=1,3,4,5,7,8,10

To test if an item exists in an array use the -Contains operator. This will return True or False:

PS C:\> $arr -contains 4
True
PS C:\> $arr -notcontains 4
False

You might use it like this:

PS C:\> if ($arr -notcontains 9) {$arr+=9}

This is pretty simple with an array like this. But you might have an array of richer objects:

PS C:\> $svc=get-service m*

Let's say we want to test if the MSIServer service is in this array. This requires a little more effort. We can't do this:

PS C:\> $svc -contains "msiserver"

What we have to do is check the name property for all the items in the array.

PS C:\> ($svc | Select -ExpandProperty Name) -contains "msiserver"
True

The -ExpandProperty parameter takes the name property and "expands" it into a string.

The code in parentheses ends up as an array of service names so -Contains now works. Now let's turn to hash tables:

PS C:\> $hash=@{Name="Jeff";Computername="Client01";OS="Windows 7";Title="Prof.
PowerShell"}
PS C:\> $hash

Name           Value
----           -----
Name           Jeff
Computername   Client01
Title          Prof. PowerShell
OS             Windows 7

One task might be to see if a specific key exists, since keys must be unique. The hashtable object has a few methods we can use, similar to the -Contains operator:

PS C:\> $hash.ContainsKey("Name")
True
PS C:\> $hash.ContainsKey("Foo")
False

You could also use the Contains() method, specifying a key name as a parameter:

PS C:\> $hash.Contains("title")
True

If you need to check for a specific value use the ContainsValue() method. However, be careful because by default case matters:

PS C:\> $hash.ContainsValue("jeff")
False
PS C:\> $hash.ContainsValue("Jeff")
True

One way around this is to simply get the hash values as an array and use -Contains:

PS C:\> ($hash.values) -contains "jeff"
True
PS C:\> ($hash.values) -contains "JEFF"
True

Here, case doesn't matter. You could do the same thing with keys:

PS C:\> ($hash.keys) -contains "title"
True

Although the ContainsKey() and Contains() methods do NOT make a case sensitive comparison so you could use easily use them. If you forget these methods, pipe your hash table object to Get-Member and you'll see them listed as methods.

PowerShell is full of these arrays, collections and hash tables and it really isn't too difficult to peek inside and find out who is at home.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular