PowerShell ForEach Loop (With Examples)

The PowerShell foreach loop runs a block of code once for every item in a collection, such as an array, a list of files or the output of a command. The current item is stored in the variable you name before in:

foreach ($item in $collection) {
    # do something with $item
}

Here’s a real one that walks through an array of office names:

$cities = 'Seattle', 'Denver', 'Austin', 'Boston'

foreach ($city in $cities) {
    "Checking the $city office"
}

Output:

Checking the Seattle office
Checking the Denver office
Checking the Austin office
Checking the Boston office
PowerShell foreach loop through an array example
A foreach loop over an array in PowerShell 7

In this guide, I’ll loop through arrays, files and hashtables, show how break and continue work, and explain the difference between foreach, ForEach-Object and the .ForEach() method.

I tested everything in PowerShell 7.6 and Windows PowerShell 5.1. The two traps near the end caught me more than once, so don’t skip them.

Loop through an array with foreach

Arrays are the most common use. You don’t need an index or a counter, and the loop stops on its own after the last item.

This one adds up a list of order amounts:

$orders = 120.50, 89.99, 240.00, 15.25
$total = 0

foreach ($amount in $orders) {
    $total += $amount
}

"Orders: $($orders.Count)  Total: {0:C}" -f $total

Output:

Orders: 4  Total: $465.74

The {0:C} format shows the total as currency. On a US system, that’s dollars with two decimals.

To loop over pipeline output instead of an array, use ForEach-Object.

Loop through files in a folder

Anything that returns objects can go after in, including a command. Here’s every log file in a folder with its size:

foreach ($file in Get-ChildItem -Path C:\psfaqs\Logs -Filter *.log) {
    '{0,-8} {1,8:N1} KB' -f $file.Name, ($file.Length / 1KB)
}

Output:

app.log       2.3 KB
sql.log      93.8 KB
web.log      17.6 KB
PowerShell foreach loop through files in a folder with their sizes
Looping through files with foreach

For more file examples, see how to loop through files in a folder with PowerShell.

Loop through a hashtable

A hashtable isn’t enumerated item by item on its own. Call GetEnumerator() so each pass gets one key/value pair:

$offices = [ordered]@{ Seattle = 'WA'; Austin = 'TX'; Boston = 'MA' }

foreach ($entry in $offices.GetEnumerator()) {
    "$($entry.Key) is in $($entry.Value)"
}

Output:

Seattle is in WA
Austin is in TX
Boston is in MA

I used [ordered] so the output keeps the order I typed. A plain hashtable doesn’t guarantee any order.

How do I get the index in a foreach loop?

The foreach statement doesn’t track the position for you. Keep your own counter:

$tasks = 'Back up the database', 'Patch the servers', 'Rotate the logs'
$i = 0

foreach ($task in $tasks) {
    $i++
    "Step ${i}: $task"
}

Output:

Step 1: Back up the database
Step 2: Patch the servers
Step 3: Rotate the logs

Note the ${i} braces. Without them, PowerShell reads $i: as a drive-qualified variable and the line breaks. If you need the index a lot, a for loop is usually cleaner.

Break and continue in a foreach loop