PowerShell Genie

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.

Lesson 2 min read Windows PowerShell 5.1 and PowerShell 7

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" }
  1. Stage 1$namesPositional 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

    PowerShell objects and pipelines documentation

    Try it

    Illustrative output · values vary by environment

    1PS> $names = 'Ada' , 'Sam' , 'Lee'
    2PS> foreach ($name in $names) { "Hello, $name" }

    Example reader

    Inspect this page's example

    Fictional browser data when supported

    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

      Keep going

      Next: PowerShell for / while / do
      Genie guidePowerShell 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.