In this next installment of my ongoing PowerShell series, I want to focus on putting PowerShell objects to work for you. Let me warn you in advance, however: Put on your advanced thinking caps for this piece, especially if you are a non-programmer or non-developer and are used to pointing at things and clicking them once or twice to accomplish some tasks. I'm going to get abstract with you here but, as far as I know, there is no way around it.
The subject? Hash tables. These are very useful tools to have in your arsenal. It just takes a while to both (a) understand them and their use fully and (b) wrap your head around the extremely funky syntax that they use. Really, the syntax is unforgiveable. I'm going to try to simplify things as much as possible.
Hash tables: The basics and fundamentals
Hash tables are a fancy way of saying "A table full of single pieces of information many times over." Those single pieces of information are known as name-value pairs, or key-value pairs as you might sometimes see them called. These pairs store a single piece of data; the key is the descriptive word about the data and the value is the actual piece of data.
A common example of key-value pairs are a list of American states and their capitals. We might call our key-value pair table "StateCapitals," for instance, and then within that table, each state would be the key, and each state's capital would be the value. We can create a sample table just to demonstrate how this would look.
StateCapitals
Key | Value |
---|---|
North Carolina | Raleigh |
California | Sacramento |
New York | Albany |
Florida | Tallahassee |
Texas | Austin |
And so on. Again, in a table for state capitals, the key would describe the state and the value would describe the capital, the thing that is in question.
Another example could be NFL teams and their mascots.
NFLMascots
Key | Value |
---|---|
Carolina | Panther |
New England | Patriot |
Seattle | Seahawk |
Dallas | Cowboy |
Atlanta | Falcon |
Again, in a table for professional football team mascots, the key would describe the team and the value would describe the actual mascot, the thing that is in question.
A hash table is actually just a table full of those key value pairs. You can start off a hash table as the value of a variable, and then you simply place an @ sign, a left curly brace, and then use '"key1" = "value1"; "key2 = "value2"' and so on. Let's use both of the above "spelled-out" tables as examples.
$StateCapitals = @{"North Carolina" = "Raleigh"; "California" = "Sacramento"; "New York" = "Albany"; "Florida" = "Tallahassee"; "Texas" = "Austin"}
$NFLMascots = @{"Carolina" = "Panther"; "New England" = "Patriot"; "Seattle" = "Seahawk"; "Dallas" = "Cowboy"; "Atlanta" = "Falcon"}
Enter those into your PowerShell window to get a feel for how they work. To check on them, just enter the variable's name at the prompt to display its value, which, if you typed correctly, should be the hash table. This shows an example of this on my system:
Converting unexpected output into something useful with hash tables
That's how you create a hash table at its most basic. Hash tables are important because some PowerShell commands will understand hash tables as values for their parameters, and one of the most common PowerShell commands you would use in this scenario is 'Select-Object.' But when you're using 'Select-Object' to pick properties to display, what happens if the content of those properties in the output isn't what you expected? Or what if the name of the property is one thing, but the command to which you want to pipe that output expects the same content to be called something else entirely? In that case, you would use hash tables along with 'Select-Object.'
'Select-Object' accepts hash tables formatted with two specific key-value pairs. Well, more specifically, it needs two keys to be present. One key is 'Name,' and the value of 'Name' is used for the column header. You can use this to rewrite the names of column headers to be something else. The other key 'Select-Object' needs is called 'Expression' -- and the value of that key needs to be a script or PowerShell code. It can be a simple script or simple code, within curly braces -- '{'and '}' -- but that is what 'Select-Object' expects there.
For the purposes of our piece here today, I'll talk about just one aspect of using hash tables with 'Select-Object'-- the ability to rewrite column names. Let's take a simple example. If you run 'Get-Process' from the PowerShell console, you get a nice table with handles, a bunch of statistics and a column header called 'ProcessName.' But what if you want to rewrite that table so it calls that column 'The Name of the Process' rather than 'ProcessName'?
You could create a hash table to do just that. That hash table is going to be built like this: First, you use 'Select-Object' because, well, that's the command. Then you use the '@' sign, which signals to PowerShell that you intend to create a hash table. Then a left curly brace '{' begins the contents of the table. Then, you type in the key 'Name' -- remember that has to be the name of the key when you use a hash table with 'Select-Object,' so hard-code that into your memory at this point. Next, use an '=' and then add the name of the column you wish to use, enclosed in quotation marks, and end with a semicolon (';').
So far that looks like this:
Select-Object @{Name = "The Name of the Process";
Next up, we add the expression. It's called 'Expression' -- and that's another hard-coding thing to remember here when hash tables are used with 'Select-Object.' Another equals sign goes in next, followed by a left curly brace -- '{' -- to signify the beginning of a PowerShell code expression.
Next, in this case, we can use the "that thing" notation ('$_') that I covered in a previous installment of this series (specifically in the story about creating scripts and loops), because it represents the object in the pipeline -- which for us, in this example, is the output of 'Get-Process.'
To access a property of 'Get-Process,' we simply add a dot ('.') and then the name of the property, which in this case is the original column header, 'ProcessName.' We then add a right curly brace to signify the end of the expression, and then a final right curly brace to signal the end of the hash table itself. That leaves us with this final 'Select-Object' statement:
Select-Object @{Name = "The Name of the Process"; Expression = {$_.ProcessName}}
Now just add the original 'Get-Process' to the front of that and you'll be golden:
Get-Process | Select-Object @{Name = "The Name of the Process"; Expression = {$_.ProcessName}}
This shows what that command returns.
You have renamed the column totally in the pipeline, without exporting it to a file and editing the resulting file. Way to transform! You're a superhero.