PowerShell foreach
foreach ($item in $collection) { } runs a block once per element. It is a language keyword, and it is not the same thing as the ForEach-Object cmdlet even though people say foreach for both.
Documentation: Microsoft Learn
Overview
The difference is real. The foreach keyword loads the entire collection into memory first, then iterates. It is faster per item and lets you use break and continue. ForEach-Object is a pipeline command: it processes objects as they arrive, uses $_ instead of a named variable, and handles a stream of millions of items without loading them all.
So the rule is straightforward. Use the foreach keyword when you already have a collection in a variable and want speed and readable loop control. Use ForEach-Object when you are in the middle of a pipeline, or the data is too large to hold at once.
Inside a foreach block, the loop variable is a normal variable you named yourself, which usually reads better than $_.
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
$names = 'Ada' , 'Sam' , 'Lee'
foreach ($name in $names) { "Hello, $name" }- Stage 1$names
Positional values or no named parameters
An example to inspect
Preview the example. Sign in for the full lesson and activities.
$names = 'Ada' , 'Sam' , 'Lee'
foreach ($name in $names) { "Hello, $name" }What happens
$names holds three strings. The loop binds each one to $name in turn and evaluates the double-quoted string, so you get three greetings. Because the collection is already in memory, this is the faster of the two forms.
Worth remembering
- foreach is a keyword. ForEach-Object is a pipeline cmdlet.
- foreach loads everything first. ForEach-Object streams.
- break and continue work in foreach, not cleanly in ForEach-Object.
- foreach names its own loop variable. ForEach-Object uses $_.
Primary documentation
Try it
Illustrative output · values vary by environment
Example reader
Inspect this page's example
Run supported commands against the practice data, or inspect the example without executing it.
Ready to inspect.
Iterates a three-element array and builds a string for each element.
Show reference output
Illustrative output · values vary by environment
Hello, Ada Hello, Sam Hello, Lee