Technical Insights • • 2 min read
Does it loop? ForEach experiences with an empty variable
A surprising PowerShell gotcha: foreach and ForEach-Object behave differently with null and empty variables. Here's what actually happens.
Does an empty variable loop in PowerShell? My first instinct was: no. But the correct answer is: it depends.
Uninitialized variable with foreach
$noValue -eq $null # True – an unregistered variable is $null
foreach ($oneValue in $noValue) {
'Do not run.'
}
# Result: does NOT enter the loop
Uninitialized variable with ForEach-Object
$noValue | ForEach-Object { 'Runs' }
# Result: DOES execute the loop body – surprising!
Empty array with foreach
$noArray = @()
foreach ($oneValue in $noArray) {
'Do not run.'
}
# Result: does NOT enter the loop
Empty array with ForEach-Object
$noArray | ForEach-Object { 'Runs' }
# Result: does NOT execute the loop body
Summary
| Input | foreach | ForEach-Object |
|---|---|---|
$null | ❌ skips | ✅ runs once |
@() | ❌ skips | ❌ skips |
To avoid surprises, initialise your variables at the start of your script.
Why does this happen?
Bruce Payette (PowerShell co-creator) explained it:
The
foreachstatement andForEach-Objecthad identical, consistent behaviour in version 1 but users complained about theforeachstatement iterating over null. As a result, we changed the behaviour in v2 (or v3 – I can’t remember which) adding a deliberate inconsistency.