PowerShell For Loop: Syntax, Examples, and Use Cases

When you need to loop a specific number of times, or when you need the current index alongside the item you’re processing, the PowerShell for loop gives you precise control that foreach doesn’t. The for loop is built around a counter variable you initialize, check, and update yourself — making it ideal for array manipulation, generating sequences, and any iteration where the index itself matters. This guide covers syntax, counting down, custom step values, nested loops, and practical examples.
Basic For Loop Syntax
The PowerShell for statement has three parts: initialization, condition, and update — separated by semicolons inside parentheses:
# for (initialize; condition; update) { body }
for ($i = 0; $i -lt 5; $i++) {
Write-Output "Iteration: $i"
}
# Inclusive upper bound — use -le for 1 through 10
for ($i = 1; $i -le 10; $i++) {
Write-Output $i
}
Iteration: 0
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
All three clauses are optional — omitting all three creates an infinite loop: for (;;) { }. In practice, always supply at minimum the condition to prevent unintended infinite loops.
Counting Down with Decrement
Reverse iteration by starting high and decrementing:
# Countdown from 5 to 1
for ($i = 5; $i -ge 1; $i--) {
Write-Output "T-minus $i"
}
Write-Output 'Launch!'
# Process array items in reverse order
$items = @('first', 'second', 'third', 'fourth')
for ($i = $items.Count - 1; $i -ge 0; $i--) {
Write-Output $items[$i]
}
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1
Launch!
fourth
third
second
first
Stepping by 2 or More
The update expression can increment by any amount:
# Every other number
for ($i = 0; $i -le 20; $i += 2) {
Write-Output $i
}
# Iterate in chunks of 100 (batch processing)
$totalRecords = 1000
$batchSize = 100
for ($start = 0; $start -lt $totalRecords; $start += $batchSize) {
$end = [Math]::Min($start + $batchSize - 1, $totalRecords - 1)
Write-Output "Processing records $start to $end"
}
0
2
4
...
20
Processing records 0 to 99
Processing records 100 to 199
...
Processing records 900 to 999
Accessing Array Items by Index
The for loop’s main advantage over foreach is having the index available:
$servers = @('web01', 'web02', 'db01', 'cache01')
# Access both index and value simultaneously
for ($i = 0; $i -lt $servers.Count; $i++) {
Write-Output "[$i] $($servers[$i])"
}
# Swap two elements
$arr = @(10, 20, 30, 40, 50)
$temp = $arr[1]
$arr[1] = $arr[3]
$arr[3] = $temp
$arr
[0] web01
[1] web02
[2] db01
[3] cache01
10
40
30
20
50
This access-by-index pattern is essential for algorithms that need to compare or swap adjacent elements, build lookup structures, or correlate two arrays of equal length by position.
Nested For Loops
Nested for loops are useful for grid traversal, matrix operations, and combination generation:
# Build a multiplication table
for ($row = 1; $row -le 5; $row++) {
$line = ''
for ($col = 1; $col -le 5; $col++) {
$product = $row * $col
$line += "$($product.ToString().PadLeft(4))"
}
Write-Output $line
}
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
For vs ForEach: Which to Choose
Choose based on what information you need inside the loop:
- Use for when you need the index, are iterating in reverse, stepping by more than 1, or operating on two arrays simultaneously by position.
- Use foreach when you just need the value and don’t care about position. It’s cleaner and reads more naturally for item-by-item processing.
- Use ForEach-Object in the pipeline when working with streaming cmdlet output.
# Prefer foreach when index isn't needed
foreach ($server in $servers) {
Write-Output $server
}
# Prefer for when index is needed
for ($i = 0; $i -lt $servers.Count; $i++) {
Write-Output "Server $i: $($servers[$i])"
}
Common Errors and Fixes
-
Off-by-one errors with array upper bound: A 4-element array has valid indexes 0–3. Using
$i -le $arr.Count(instead of-lt) accesses index 4, returning$nullsilently. Always use$i -lt $arr.Countfor zero-based arrays. -
Modifying loop variable inside body: Assigning to
$iinside the loop body changes the counter and can cause skipped iterations or premature termination. If you need a separate counter, declare a different variable name inside the body.
Related Cmdlets / See Also
Wrapping Up
The PowerShell for loop gives you precise counter control for index-based iteration, reverse loops, and batch processing. Use it when you need the index — otherwise, foreach is cleaner. Always use -lt $arr.Count for array bounds to avoid off-by-one errors. Your next step: try the batch-processing pattern above on a real dataset from your environment.


