Search notes:

PowerShell: Hash table

A hash table stores key/value pairs.
In other programming languages, a hash table is also referred to as dictionary or associative array.
Hash tables are generally (but not exclusively!) used to store a list of items where each item is uniquely identified by a name and where someone has an interest in looking up the respective item's value for a given name.
A good example are environment variables. In fact, [System.Environment]::GetEnvironmentVariables() returns such a hashtable:
PS C:\> [System.Environment]::GetEnvironmentVariables().GetType().FullName
System.Collections.Hashtable
PS C:\> [System.Environment]::GetEnvironmentVariables()
Name                           Value
----                           -----
SESSIONNAME                    Console
ProgramFiles(x86)              C:\Program Files (x86)
USERDNSDOMAIN                  TQ84.LOCAL
…
A hash table's underlying .NET class is System.Collections.Hashtable.

Creating hash tables

A hash table is constructed with the @{ … } syntax.
If multiple key/value pairs are declared on the same line, they need to be separated by a semicolon (;).
One-word keys may be written unquoted.
PS C:\> $ht = @{ foo = 42; bar = 99; baz = 0}
PS C:\> write-output $ht['bar']
99
There are also ordered hash tables where keys always show up in the same order in which they were defined. Such hash tables are created like so:
PS C:\> $hto = [ordered] @{ foo = 42; bar = 99; baz = 0}
Note: although [ordered] with its square brackets looks like a type accelerator, it is not.
Compare with @( … ) (the array subexpression operator) which creates arrays from the expression within its parentheses (even if the expression evaluates to zero or only one element).
A hash table can also be constructed with the constructor of System.Collections.Hashtable whose type accelerator is [hashtable]:
$ht = [hashtable]::new()

Adding and removing keys

#
# Create hash table with two elements;
#
$htA = @{
  a_1 = 'val one';
  a_x = 'val X'
}

#
# Add another element
#
$htA['a_2'] = 'val two'

#
# Remove an element
#
$htA.remove('a_x')

write-output $htA
#
# Name                           Value
# ----                           -----
# a_1                            val one
# a_2                            val two

#
# Create another hashtable
#
$htB = @{
  b_1 = 'VAL ONE';
  b_2 = 'VAL TWO'
}

#
# The + and += operators allow to merge
# two hash tables (IF they don't share a key name):
#
$htA += $htB

write-output $htA
#
# b_2                            VAL TWO
# a_1                            val one
# b_1                            VAL ONE
# a_2                            val two
Github repository about-PowerShell, path: /language/type/hash-table/add-remove.ps1

Declaring variables as hash table

The type accelerator [hashtable] allows to declare a variable as a hash table:
[hashtable] $ht

Members/properties seem to be overridden by adding keys (collissions)

A hash table has predefined members (properties such as keys and methods such as Add()). When a key is added with the same name, the key name seems to override the already existing property. Of course, this is less than desirable.
It is possible to access the original members via the intrinsic member psBase.
This is demonstrated with the following scriptlet:
#
#  Create a hash table
#
$ht = @{}

#
#  Add a couple of key/value pairs:
#
$ht['one'] = 1
$ht['two'] = 2

#
#  Use the 'Keys' property to print the
#  hash table's
#
$ht.Keys
#
#  one
#  two

#
#  Add another key/value pair.
#
$ht['Keys'] = 42

#
#  Adding this key overwrode the
# 'Keys' property:
#
$ht.Keys
#
#  42

#
#  Use psBase.Keys to get the «real»
#  Keys property:
#
$ht.psBase.Keys
#
#  one
#  Keys
#  two


#
#  Can 'psBase' be overridden, too?
#
$ht['psBase'] = $null

#
#  No, it does not:
#
$ht.psBase.Keys
#
#  psBase
#  one
#  Keys
#  two
Github repository about-PowerShell, path: /language/type/hash-table/override-members.ps1

.NET types

A hash table is implemented using the System.Collections.Hashtable .NET class:
PS C:\> ( @{} ).GetType().FullName
System.Collections.Hashtable
An ordered hash table is a System.Collections.Specialized.OrderedDictionary:
PS C:\> ( [ordered] @{} ).GetType().FullName
System.Collections.Specialized.OrderedDictionary

Sorting keys or values

The elements in a hash table can be sorted based on the value of their key or value. For a reason I don't really understand, the GetEnumerator() method must be called on the hash table before piping the hash table into sort-object:
$ht = @{
  'seven'      =  7;
  'eleven'     = 11;
  'five'       =  5;
  'forty-two'  = 42;
  'zero'       =  0;
  'eighty-two' = 82;
}

$ht.GetEnumerator() | sort-object -property name # -property key seems also possible
#
# Name                           Value
# ----                           -----
# eighty-two                     82
# eleven                         11
# five                           5
# forty-two                      42
# seven                          7
# zero                           0

$ht.GetEnumerator() | sort-object -property value
#
# zero                           0
# five                           5
# seven                          7
# eleven                         11
# forty-two                      42
# eighty-two                     82
Github repository about-PowerShell, path: /language/type/hash-table/sort.ps1

See also

The convertFrom-stringData creates a hash table from a string that contains key/value pairs.
Some cmdlets require a hash table, for example the -colors option of set-psReadLineOption.
The -asHashTable option of the cmdLet group-object.
new-object psObject
Converting a hash table to a psCustomObject
System.Collections.Generic.Dictionary<TKey, TValue> provides strongly typed key/value dictionary.
The preference variable $psDefaultParameterValues is a hashtable.
Datatypes in PowerShell

Index