Associative Arrays


Associative arrays are special types of arrays. Think of them as a way of relating, or associating one piece of data with another piece of data. For example, they're useful for performing certain types of data lookup that we'll see in this chapter. You may also see associative arrays referred to as dictionaries or hash tables.

An associative array is a data structure that stores multiple key-value pairs. Think of them as a kind of table:

Key

Value

Don

Blue

Chris

Pink

Jeffery

Blue

The key is usually some piece of well-known or easily-obtained information, while the value is the data you want to look up. Keys are unique in the array, while values can be repeated as necessary. In our table example, the associative array keys are a person's name, while each corresponding value is the person's favorite color. Notice that the key names are unique while data values can be duplicated.

PowerShell uses the hash table data type to store the contents of an associative array because that data type provides fast performance when looking up data. What's really neat about associative arrays is that the individual values can be of different types. In other words, one key might be connected to a string, while another is connected to an XML document. This lets you store any kind of arbitrary data you want in an array.

Creating an Associative Array

The @ operator is used to create an associative array as follows:

 $aa = @{"Don"="Blue"; "Chris"="Pink"; "Jeffery"="Blue"} 

This creates an associative array with three keys and three values, exactly as shown in the previous table. Of course, the values don't have to be simple strings. Instead they can be numbers, the output from a cmdlet, or even entire other associative arrays. We'll take a closer look at this later in the chapter.

Using an Associative Array

You can display the entire contents of an associative array by calling its name:

 PS C:\> $aa = @{"Don"="Blue"; "Chris"="Pink"; "Jeffery"="Blue"} PS C:\> $aa Name                           Value ----                           ----- Jeffery                        Blue Chris                          Pink Don                            Blue PS C:\> 

However, normally you'd want to access a single element:

 PS C:\> $aa."Don" Blue PS C:\> 

Type the associative array variable name, a period, and then the key you want to retrieve. PowerShell will respond by displaying the associated value. Note that keys and values, if the values are strings, can be contained in single or double quotes just like any other string. Keys are always expected to be strings, and so usually need to be enclosed in quotes.

However, the quotes can be omitted if the key doesn't contain any spaces, periods, or other word-breaking characters:

 PS C:\> $aa.Don Blue PS C:\> 

To check and see what data type a particular key's value is:

 PS C:\> $aa.Don.GetType() IsPublic IsSerial Name                                    BaseType -------- -------- ----                                    -------- True     True     String                                  System.Object 

A single value within an associative array can actually be another associative array:

 PS C:\> $aa2 = @{Key1="Value1"; Colors=$aa} PS C:\> $aa2.Colors Name                           Value ----                           ----- Jeffery                        Blue Chris                          Pink Don                            Blue PS C:\> $aa2.Colors.Don Blue PS C:\> 

In this example a new associative array is named $aa2. It has two keys: 1) Key1, which has a value of "Value1"; and 2) Colors, which is assigned the associative array $aa we used earlier as its value. Displaying $aa2.Colors displays the entire $aa associative array, while $aa2.Colors.Don accesses a single key within the $aa associative array.

Let's take a look at a more practical example. First, we'll demonstrate that an associative array can contain just about any type of value:

 PS C:\> $systems=@{"XPLAP01"=get-wmiobject -class win32_computersystem} PS C:\> $systems Name                           Value ----                           ----- XPLAP01                          \\XPLAP01\root\cimv2:Win32_ComputerSy PS C:\> $systems.XPLAP01 Domain              : myit.local Manufacturer        : Dell Computer Corporation Model               : Latitude D800 Name                : XPLAP01 PrimaryOwnerName    : Admin TotalPhysicalMemory : 1609805824 

Here we've created an associative array called $systems with a single element. The key is XPLAP01 and the data value is a WMI object representing an instance of the Win32_Computersystem class. Invoking just the array name displays the contents, which in this case is a single computer. If we want to see the value of the XPLAP01 key we $systems.XPLAP01.

If the key name has a space you will have to use:

 $myArray.'Test User' 

Alternatively, you can use:

 $myArray.['Test User'] 

If we know the name of a specific WMI object attribute, we can return its value with a command like this:

 PS C:\> $systems.xplap01.totalphysicalmemory 1609805824 PS C:\> 

This works because the value associated with key XPLAP01 is a WMI object. Therefore, we can use dotted notation to display a specific property value.

Let's add a second system to the array:

 PS C:\> $systems.DC01=get-wmiobject -class "win32_computersystem" -computername "MYIT-DC01" 

We can easily define a new key and value by setting the value for the new key using dotted notation. If you were to run $systems.count, it would return a value of 2. Appendix B has a complete list of an associative array's methods and properties.

Now that we have more than one item in the array, we can use the Keys and Values properties to get more than one key or value:

 PS C:\> $systems.keys DC01 XPLAP01 PS C:\> $systems.values Domain              : myit.local Manufacturer        : MICRO-STAR INTERNATIONAL CO., LTD Model               : KM400-8235 Name                : DC01 PrimaryOwnerName    : ADMIN TotalPhysicalMemory : 1073168384 Domain              : myit.local Manufacturer        : Dell Computer Corporation Model               : Latitude D800 Name                : XPLAP01 PrimaryOwnerName    : Admin TotalPhysicalMemory : 1609805824 PS C:\> 

Suppose we read a text list of computers and build the associative array. As we've shown, with this type of array you can get the associated data by specifying the key.

However, if we want to enumerate the array and display only the computer's model as part of a hardware inventory, we would use code like this:

 PS C:\> $keys=$systems.Get_Keys() 

This code stores the keys in a yet another array called $keys. Technically, $keys is a collection that is basically a list. We can now use the ForEach cmdlet to iterate through the associative array:

 PS C:\> foreach ($key in $keys) {write-host $key $systems.$key.Model} DC01 KM400-8235 XPLAP01 Latitude D800 PS C:\> 

There's a lot going on in this single command so let's take it apart. We start with the basic ForEach cmdlet that says for each item in the $keys collection, set it to the $key variable. As we loop through, $key becomes DC01 and XPLAP01 and so on, assuming we had a larger array. Then for each pass, ForEach runs the code in the curly braces. The brace code calls the Write-Host cmdlet that displays the value of $key and the model property from the WMI object value of the corresponding key in $systems.

That last part can get a little confusing. Remember, the first time through the value of $key is DC01. So $systems.$key.model is the equivalent of typing $systems.dc01.model. As we discussed earlier, $systems.dc01 returns the corresponding value that is a WMI Win32_Computersystem object. Since this is an object, we can get the model property value merely by asking for it. This process is repeated for every item in $keys.

In the traditional text-based shell this type of coding would be complicated and involve a lot of string parsing and manipulation. However, because PowerShell works with objects, even if they are in arrays, we can manipulate the object and let PowerShell display the final results in just about whatever text format we want.



Windows PowerShell. TFM
Internet Forensics
ISBN: 982131445
EAN: 2147483647
Year: 2004
Pages: 289

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net