Get to Know Hash Tables for PowerShell

Get to Know Hash Tables for PowerShell

Although poorly named, they’re useful administrative shortcuts

I hate the name hash tables. But I do like what hash tables can do, so I’m compelled to show you a little bit about them. They’re often used quite effectively as Windows Power Tools.

I’ve talked a lot about Set-ADuser, the almost-does-it-all PowerShell cmdlet for changing user characteristics. Generally, its syntax is straightforward, as in the case where I might want to change Paul’s title to Engineer:

set-aduser Paul -title Engineer

That command is very nice, easy to read, and—I would argue—faster than firing up the GUI to make the same change. But Active Directory (AD) accounts have more than a hundred attributes (more if you’ve added Exchange Server to your organization). Although there are parameters named -title, -manager and so on, the Directory Services team didn’t create a parameter for every attribute. (For example, there’s no -countrycode parameter.) More important, the team couldn’t create a parameter for every attribute in your users’ accounts, because you might have modified your AD schema (as, again, when you add Exchange) and have no way of knowing what parameters you need!

That’s why the team created a parameter called –replace, which lets you change any of your AD account's attributes—even the ones you added after the fact. You can also use it to change more than one attribute at a time, as in this nice, compact command:

set-aduser –replace @{title="Writer"; middlename="Jerome"; mail="[email protected]"}

But wait, what’s all that stuff following the first @ symbol? What’s with the braces and semicolons? Well, that’s the hash table I mentioned at the start of this column. PowerShell uses hash tables quite a lot. Figure 1 shows a picture of one.

Daunting as the phrase hash table is (don't they have those at breakfast buffets?), it's really nothing more than a two-column list of names and values. Pretty simple, right? In a better world, computer scientists would stop saying hash table and start saying something like dictionary table. Some computing tools do call them dictionaries, but they're in the minority, for a goofy historical reason. Back when computers were young, compiler designers needed a way to store lists of data. The first was an array, which Figure 2 shows.

This array is a table of data that some programmer needed. He or she would ask for a given value, retrieve the third entry, and get the value Fish. Those index values are sequential integers, and computers like numbers.  With hash tables, compiler designers replaced the simple integers with names—random bits of text that weren't sorted, didn't have any notion of sequentiality, and thus were difficult to implement. But how would they make that work? Eventually someone hit on the idea of running the names through a hashing function, which produced numbers. The problem was solved, rejoicing commenced, and the name stuck. So go ahead and hate the name—but love the utility of hash tables.

Hash tables in PowerShell look like

@{name1="value1"; name2="value2"; name3 = "value3"…}

They start with @{, then contain name/value pairs joined by an equal sign. Values are in quotes (if text), and each pair is separated by a semicolon. You can create a hash table and store it in a variable, then look at it, like so:

PS C:\> $h = @{bug="insect";roses="red";height="31"}
PS C:\> $h

Name                           Value
----                           -----
roses                          red
bug                            insect
height                         31

You can even add entries to a hash table. For example, if you typed [email protected]{shoesize="13E"}, you’d gain a fourth entry in the hash table. Where would that be useful? Consider again Set-ADuser -replace’s use of a hash table. Hash tables are flexible and open-ended, so imagine that you were given a massive spreadsheet of edits to AD account attributes. You could export that to a CSV file (which PowerShell understands), then read in the entries for a given user and build the hash table of changes to that user’s account. If you stored the user’s name in $uname and accumulated the attribute changes into a hash table you called $attchange, getting AD to make all those changes would be as simple as

set-aduser $uname –replace $attchange

Yet another PowerShell use for hash tables is the splat, an alternative way to type any command. Suppose you’ve got a command like

get-aduser –filter {enabled –eq $false} –searchbase "OU=TPs,DC=bigfirm,dc=com" –properties title,office

You could create a hash table in which the parameters are the names, and the arguments for those parameters are the values, as in

[email protected]{Filter = "Enabled -eq '$false'"; searchbase="dc=bigfirm,dc=com" ; properties=("Title","Office")}

Then you’d need only type

get-aduser @p

and it would run with the parameters in the hash table. Notice the @ symbol on the Get-ADuser invocation: The variable ends with a $ (of course), but when feeding the hash table to the command, you’d prefix the name with the @. The bottom line is that although hash tables have a bad name, they're useful if you understand them—and PowerShell uses them a lot. So add them to your toolkit!

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.