Collections and key/value maps hold the data of every non-trivial script.
Arrays are created with commas or @( ): $a = 1, 2, 3 or $a = @('x', 'y'). Index from 0 and from the end with negatives: $a[0], $a[-1]; slices with ranges: $a[0..1]. $a.Count gives the length. Arrays are fixed-size: $a += 4 builds a whole new array each time, which is fine for a handful of items and slow for thousands. For growing collections use [System.Collections.Generic.List[object]] (or a typed List[string]) and .Add().
@( ... ) around a command guarantees an array, even when the command returns zero or one item, so .Count and indexing always behave.
Hashtables map keys to values: $h = @{ Name = 'Ada'; Role = 'admin' }. Read with $h.Name or $h['Name'], add by assigning a new key, test with .ContainsKey(), remove with .Remove(). Keys are case-insensitive by default. A plain hashtable does not keep insertion order; [ordered]@{ } does, which matters for output and JSON.
To loop over a hashtable, iterate $h.GetEnumerator() (giving .Key and .Value) or $h.Keys. Hashtables are also used for splatting: $params = @{ Path = '.'; Recurse = $true }; Get-ChildItem @params passes keys as named parameters, which keeps long commands readable.
Example
$fruits = @('apple', 'banana')
$fruits += 'cherry' # creates a NEW array
$fruits[0]; $fruits[-1] # apple / cherry
$fruits.Count # 3
$fruits -contains 'kiwi' # False
$list = [System.Collections.Generic.List[string]]::new()
$list.Add('fast'); $list.Count # 1 (use for big, growing lists)
$user = @{ Name = 'Ada'; Role = 'admin' }
$user.Name # Ada
$user['role'] # admin (keys are case-insensitive)
$user.Email = 'ada@example.com' # add a key
$user.ContainsKey('Email') # True
$ordered = [ordered]@{ b = 2; a = 1 }
$ordered.Keys -join ',' # b,a (insertion order kept)
foreach ($kv in $ordered.GetEnumerator()) { "$($kv.Key)=$($kv.Value)" } # b=2 / a=1
$params = @{ Path = $PSHOME; Filter = '*.json' }
@(Get-ChildItem @params).Count -gt 0 # True (splatting + @() for an array)Remember
- Arrays: 1, 2, 3 or @(); += copies, use List[T] for growth
- @{ } hashtable, [ordered]@{ } keeps key order
- Splat a hashtable of parameters with @params
Watch out for
- Building a large result with
$results += $itemin a loop: it is quadratic.