The other day I wrote an entry about using the Dictionary object in VBScript . I alluded to how you could use a hash table in PowerShell. Let me show you how and I think you’ll also appreciate how much more you can do with them in PowerShell with less coding.
You can create a hash table with entries by specifying a key=value pair separated by semicolons.
#create a hash table with values
$hash=@{Name="Jeff Hicks";Title="Scripting Guru";
Url="blog.sapien.com";Extension="x123"}
#view the contents
$hash
Viewing the hash produces output like this:
Name Value
—- —–
Name Jeff Hicks
Url blog.sapien.com
Extension x123
Title Scripting Guru
Or you can create an empty hash table.
#create an empty hash table
$hash=@{}
So you can compare the two approaches I’ll use the same idea as my entry on the Dictionary object. I’ll use ADSI to get all local user accounts and store the name and password age, formatted in days, in the hash table.
$computername=$env:computername
[ADSI]$Server="WinNT://$computername"
$users=$server.psbase.children | where {
$_.psbase.schemaclassname -eq "user"
}
#add items to the hash table
foreach ($user in $users) {
$hash.Add($user.name[0],($user.passwordage[0]/86400 -as [int]))
}
The Add() method requires that you specify the key and associated item. The Count property will return the number of items in the hash table.
Write-Host ("There are {0} users in the hash table." -f $hash.count)
To see if a key exists, use the ContainsKey() method which returns True or False. By the way there is also a ContainsValue() method.
#see if a key exists and if so get its value
if ($hash.containsKey("administrator")) {
Write-Host ("{0} Administrator Password age = {1} days" -f
$computername,$hash.Item("administrator"))
}
I can get the corresponding value for the “administrator” item using the Item property. This is a VBScript-like approach. PowerShell let’s me get the values using an object.property representation. Both of these will return the associated value.
#or access items by key
$hash.Administrator
#or like this
$hash["administrator"]
By now you know you can view the contents by simply typing the variable name at a PowerShell prompt. Like the Dictionary object, the hash table doesn’t have a Sort method, but no matter since PowerShell has a Sort-Object cmdlet.
#view the contents sorted by key
$hash.GetEnumerator() | sort
#or by value
$hash.GetEnumerator() | sort value -descending
To remove a single item it can’t get any easier than using the Remove() method.
#remove an item
if ($hash.containskey("guest")) {
$hash.remove("guest")
}
If you forget any of these methods or properties you can always pipe your hash table to Get-Member.
Often you will want to do something with the data in the hash table. Here’s an example using the user accounts.
$hash.keys | foreach {
$lastChanged=((Get-Date).AddDays(-($hash.item($_)))).ToShortDateString()
$obj=New-Object PSObject
$obj | Add-Member Noteproperty "Computer" $computername
$obj | Add-Member Noteproperty "User" $_
$obj | Add-Member Noteproperty "PasswordAge" $hash.item($_)
$obj | Add-Member Noteproperty "LastChanged" $lastChanged
write $obj
} | sort PasswordAge -descending | Format-Table -Autosize
Like the VBScript Dictionary object, the Keys property returns a collection of keys. Here I’m piping them to ForEach. Remember that $hash.item($_) will return the corresponding value. The first line is getting the date the password was last changed by using the value as a negative number in the AddDays() method and then formatting it as a short date. The rest of the code creates a custom object and defines properties using data from the hash table as values. The benefit is that I can pipe this output to Sort-Object and Format-Table.
Computer User PasswordAge LastChanged
——– —- ———– ———–
CHAOS Jeff 185 8/18/2008
CHAOS Administrator 170 9/2/2008
CHAOS MyNewUser 134 10/8/2008
CHAOS daisy 38 1/12/2009
CHAOS lucky 38 1/12/2009
CHAOS __vmware_user__ 2 2/17/2009
To remove all items from the hash table simply call the Clear() method.
#remove all
$hash.Clear()
There are many opportunities for using hash tables in PowerShell, even more in PowerShell v2.0. See About_Associative_Array in PowerShell v1.0 and About_Hash_Tables in PowerShell v2.0 CTP3. Don’t forget there is coverage on this topic as well in Windows PowerShell v1.0: TFM 2nd Edition
Download a script file with all these examples here.