Hashtables in PowerShell can be utilized to retailer data in a structured method. That is completed through the use of key/worth pairs permitting you to simply extract the wanted data from the hashtable. You’ll be able to examine a hashtable in PowerShell with an associative array if you need.
Hashtables are used very often in PowerShell as a result of they’re a good way to retailer and course of data. The beauty of hashtables is that the important thing and worth might be any object sort. So you aren’t restricted to integers and strings, however you can too create nested hashtables for instance.
On this article, we’re going to try hashtables and learn how to use them in your PowerShell scripts.
Hashtable vs Array
Earlier than we’re going to take have a look at hashtables, let’s first clarify the distinction between hashtables and arrays. This can be a query that’s usually requested, and other people get usually confused between the 2.
An array is an listed record of values. The index is mechanically generated while you add values to the array. So that you don’t have management over the place you retailer the data within the array.
$array = @('apple','raspberry','kiwi')
We will entry the gadgets within the array by looping via them or accessing the gadgets by their index quantity:
$array | Foreach { Write-Host $_ } # Consequence apple raspberry kiwi # Or by index quantity write-host $array[1] # Consequence raspberry
We will additionally add or replace values in an array, however we will’t change or decide the index variety of the merchandise:
# Substitute the raspberry with melon $array[1] = 'melon' # Add a fruit to the array $array += 'banana'
Hashtable
As we’ve got seen an array is only a record (assortment) of things, which we will add, modify or take away from the record. The index is mechanically generated while you add gadgets to it. Quite the opposite, with a PowerShell HashTable, we should outline the index (keys) of the worth that we wish to add.
To create a hashtable we use {}
as an alternative of ()
:
# Making a hashtable $serverIps= @{} # Or making a pre-populate hashtable $serverIps= @{ 'la-srv-lab02' = '192.168.10.2' 'la-srv-db01' = '192.168.10.100' }
So as to add a server’s IP Tackle to the hashtable we might want to outline a key. We will’t do merely $hashtable.add('worth')
, as a result of the hashtable received’t create an index mechanically.
$key = 'la-srv-lab01' $worth="192.168.10.1" $serverIps.add($key,$worth) # Or just $serverIps.add('la-srv-lab03','192.168.10.3') # Consequence: $serverips Identify Worth ---- ----- la-srv-lab03 192.168.10.3 la-srv-lab01 192.168.10.1
The important thing on this case is the server title and the worth of the IP Tackle of the server. If we’d like the IP Tackle of the lab03 server we will merely do the next:
Retrieving information from a Hashtable
To retrieve information from the hashtable in PowerShell we will merely specify the important thing, which is able to return the worth of the important thing:
$serverIps['la-srv-lab03'] # Consequence 192.168.10.3
Another choice is to iterate via the hashtable, however this works a bit in a different way in comparison with an array. If we simply merely pipe a foreach behind the hashtable, you’ll discover that it solely returns a hashtable object:
$serverIps | foreach {write-host $_} System.Collections.Hashtable
To get solely the values from the hashtable we will use the .worth
property:
# Return solely the values $serverIps.values # Or pipe them in a foreach to ping the servers for instance: $serverIps.values | foreach {ping $_}
When working with a hashtable you in all probability additionally wish to retrieve the info as key/worth pairs. For this, we will use the GetEnumerator
perform:
$serverIps.GetEnumerator() | ForEach-Object { $end result="{0} IP tackle is {1}" -f $_.key, $_.worth write-host $end result } # Consequence la-srv-lab03 IP tackle is 192.168.10.3 la-srv-lab01 IP tackle is 192.168.10.1
Updating values
Updating values in a hashtable might be completed through the use of the important thing to pick the proper key/worth pair:
$serverIps['la-srv-lab03'] = '192.168.10.5'
If it is advisable to replace a number of values in a hashtable, you’ll be able to’t merely use a ForEach loop to iterate via the hashtable. For instance, this received’t work:
$serverIps.Keys | ForEach-Object { $serverIps[$_] = '192.168.10.20' }
You’ll first must clone the keys earlier than you’ll be able to replace the values:
$serverIps.Keys.Clone() | ForEach-Object { $serverIps[$_] = '192.168.10.20' }
Eradicating keys or values
To utterly take away a key/worth pair from the hashtable you should utilize the .take away
perform. You will have to specify the important thing that you simply wish to take away:
$serverIps.Take away('la-srv-lab03')
It’s additionally potential to take away solely the worth from a key:
$serverIps['la-srv-lab03'] = $null
To utterly clear the hashtable you might have two choices, you’ll be able to recreate the hashtable occasion or use the clear perform. The latter is most well-liked as a result of it makes your code simpler to learn.
# Recreate the hashtable occasion $serverIps = @{} # Higher possibility for readability, use the clear perform $serverIps.clear()
Splatting hashtables
Some cmdlets in PowerShell require loads of properties that we usually all write on a single line. This may make your PowerShell scripts tougher to learn since you would possibly must scroll horizontally to view the whole command.
For instance, while you wish to ship an e-mail from PowerShell, you’ll find yourself with a protracted line of parameters
Ship-MailMessage -SmtpServer smtp.contoso.com -To [email protected] -From [email protected] -Topic 'tremendous lengthy topic goes right here' -Physique 'Take a look at e-mail from PowerShell' -Precedence Excessive
To make this extra readable we will use a hashtable and splat it. Splatting replaces all of the parameters and values with a single variable. Notice that we use the @
image to splat the variable as an alternative of $
$mail = @{ SmtpServer="smtp.contoso.com" To = '[email protected]' From = '[email protected]' Topic="tremendous lengthy topic goes right here" Physique = 'Take a look at e-mail from PowerShell' Precedence = Excessive } # Notice the @ infront of mail, as an alternative of $ Ship-MailMessage @mail
As you’ll be able to see, splatting makes your code simpler to learn and keep as an alternative of a protracted line of parameters.
Creating Objects from Hashtables
Hashtables are nice when it is advisable to construction information for a single object or for splatting, however they don’t seem to be true objects. Hashtables solely have two columns, key, and worth. So we will create a hashtable with the specs of a single server, however when we have to retailer information about a number of servers we run into limitations (we will’t reuse column names for instance).
So a greater method to construction your information when you might have a number of entries is to make use of objects. The best method to create objects in PowerShell is to transform a hashtable to a customized PowerShell object. We do that by including [pscustomobject] in entrance of the hashtable.
Take the next instance, first we create a hashtable with server specs:
$servers = @{ 'title' = 'la-srv-db01' 'ip' = '192.168.10.100' 'mannequin' = 'Hp DL380 G10' 'reminiscence' = '96Gb' } # Consequence Identify Worth ---- ----- reminiscence 96Gb ip 192.168.10.100 title la-srv-db01 mannequin Hp DL380 G10
As you’ll be able to see, we solely have two columns, title and worth. The hashtable represents a single server and we will’t use it to create an inventory of servers.
Nonetheless, if we convert the hashtable to a customized PowerShell object we get an precise desk, the place we’ve got a number of columns.
$servers = [pscustomobject]@{ 'title' = 'la-srv-db01' 'ip' = '192.168.10.100' 'mannequin' = 'Hp DL380 G10' 'reminiscence' = '96Gb' } # Consequence title ip mannequin reminiscence ---- -- ----- ------ la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb
So now we will add one other server to the pscustomobject
as effectively:
perform servers { [pscustomobject]@{ 'title' = 'la-srv-db01' 'ip' = '192.168.10.100' 'mannequin' = 'Hp DL380 G10' 'reminiscence' = '96Gb' } [pscustomobject]@{ 'title' = 'la-srv-lab03' 'ip' = '192.168.10.3' 'mannequin' = 'Hp DL180 G9' 'reminiscence' = '32Gb' } } servers # Consequence title ip mannequin reminiscence ---- -- ----- ------ la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb la-srv-lab03 192.168.10.3 Hp DL180 G9 32Gb
Exporting Hashtable to CSV
While you export a hashtable to CSV you’ll discover that by default the important thing and values as not exported. The output will solely include details about the hashtable object, not the info contained in the hashtable.
To really export the contents of the hashtable you will want to make use of the GetEnumerator technique, identical to we did with viewing the contents of the hashtable. We solely want the Key and Worth from the hashtable, so you will want so as to add a choose to the command as effectively.
$serverIps= @{ 'la-srv-lab02' = '192.168.10.2' 'la-srv-db01' = '192.168.10.100' 'la-srv-lab03' = '192.168.10.3' } $serverIps.GetEnumerator() | Choose Key, Worth | Export-CSV -path c:temphash.csv -No
Wrapping Up
Hashtables in PowerShell are a good way to construction information or to make use of together with splatting. Nonetheless, take into account that they’re supposed to make use of for less than a single merchandise. We will’t create a customized column or retailer a number of rows with the identical key. For that, you actually need to make use of the customized PowerShell Objects.
I hope you discovered this text helpful, in case you have any questions, simply drop a remark beneath.
If you wish to be taught extra about PowerShell, just remember to additionally learn the Prime 10 PowerShell Instructions that you should know