Differences Between PowerShell’s For and ForEach Loops

Windows PowerShell Loops Explained

PowerShell has a variety of methods for stepping through data.  The purpose of this page is to explain the differences between, 'For' and ForEach loops, and also how they in turn differ from the ForEach-Object cmdlet.

Differences Bettween PowerShell Loops


For (Statement) -v- ForEach (Loop)

My best advice is just keep examining these looping methods until you arrive at a pet way of differentiating between them.  As for me I think of 'For' as needing to be initialised, whereas, I think of 'ForEach' as needing the 'in' keyword.

Example 1: PowerShell's For Loop

Let us examine the official Microsoft PowerShell syntax:

For (<init>; <condition>; <repeat>) {<command_block>}

Learning Points
Every item of PowerShell's syntax is loaded with meaning. Take the (parenthesis) they contain the statement, where as {curly braces} hold the block command or payload.

One more point,  while Example 1 contains no 'In' keyword, look out for this tiny, but vital word when you study Example 2 the ForEach-Object loop.

Task: To Calculate the 14 times table

'For' is more flexible than ForEach in the sense that the <repeat> section of For allows increments other than 1, the example below adds 14 at each step.

For ( $i = 14; $i -le 200; $i+=14 ) { $i }

Learning Points 
One element of the For statement that sticks in my mind is <init>, it is present and compulsory here, but absent in statement section of the ForEach loop.

You can initiate the $i variable inside or outside the statement:

$i =14
For ( ; $i -le 200; $i+=14 ) { $i }

Note 1: If you initiate the variable before the loop, remember you still need a semicolon to mark the first element of the statement.

Example 2: ForEach 'In' Array

Begin by studying the brackets: use (parenthesis) for the compulsory or control structure, followed by the {braces} for the block command.  Then note the key feature of the ForEach loop, the tiny word 'in'.

ForEach ($<item> in $<collection>){<statement list>}

Here we have the same task as Example 1, namely calculating the 14 times table, but this time we are going to step through the values with ForEach.

$Multiplier = 14
$Tables = @(1,2,3,4,5,6,14,8,9,10)
ForEach ($Item in $Tables) {
"$Item" +" x " + $Multiplier + " = " + ($Item * $Multiplier)

Learning Points
Although you don't have to explicitly declare an array: @(1,2..) this method does highlight one of the differences between ForEach and plain 'For'.

Note 2: Being an array, you could simplify to: $Tables = @(1..10)

Guy Recommends:  A Free Trial of the Network Performance Monitor (NPM)Review of Orion NPM v11.5 v11.5

SolarWinds’ Network Performance Monitor will help you discover what’s happening on your network.  This utility will also guide you through troubleshooting; the dashboard will indicate whether the root cause is a broken link, faulty equipment or resource overload.

What I like best is the way NPM suggests solutions to network problems.  Its also has the ability to monitor the health of individual VMware virtual machines.  If you are interested in troubleshooting, and creating network maps, then I recommend that you try NPM now.

Download a free trial of Solarwinds’ Network Performance Monitor

Piping Objects Into a Loop

There are occasions in PowerShell where you want to process the output produced by cmdlets such as Get-ChildItem or Get-Process.  Neither 'For' nor ForEach can handle piping; to execute this classic (|) PowerShell technique, you need a cmdlet called ForEach-Object

The key to appreciating the difference between ForEach and ForEach-Object is to make the connection between the noun 'Object' and (|) piping. For example, you can pipe a collection of items such as files, or processes into this cmdlet and then use a {block statement} to manipulate the data.

Example 3: ForEach-Object Cmdlet

Our task is to list task manager processes with a base priority greater than 9.

Get-Process | ForEach-Object {
If ($_.BasePriority -ge "9") {"{0,-25} {1,10} " -f $_.Name, $_.BasePriority}

Note 3: There are other ways of obtaining the same information, for example piping into a Where-Object clause.

Learning Points
Remember that ForEach-Object is a cmdlet, and therefore has parameters such as -Begin and -End for refining your script, and also -Confirm and -WhatIf for testing.  My point is that 'For' and plain 'ForEach' are just constructs, they have no parameters.

See more about ForEach-Object loops ยป

Loop Planning and Objectives

It's possible to achieve the same result by using different methods, thus choosing the right type of loop depends on your objective. For example, it surprised me that Example 1 – the plain For statement, was 30 times faster than the ForEach Loop in Example 2.  Try it for yourself with Measure-Command.

If, however you want to display the results neatly in the format 3 x 14 = 42, then the ForEach loop is the way to go, after all you can afford a few extra milliseconds.

Warning: Sooner or later an experiment results in an endless loop, you can break-out of such a non-stop cycle by pressing Ctrl +c.


I have described the For statement and ForEach 'In' loop in my own words; however, you can compare my thoughts with Microsoft's definitions by accessing PowerShell's built-in help:

Get-Help about_For
# Also a different file called
# Get-Help about-ForEach

As for the ForEach-Object cmdlet, that has it's own help file.

Engineer's Toolset v10Guy Recommends: SolarWinds Engineer’s Toolset v10

This Engineer’s Toolset v10 provides a comprehensive console of 50 utilities for troubleshooting computer problems.  Guy says it helps me monitor what’s occurring on the network, and each tool teaches me more about how the underlying system operates.

There are so many good gadgets; it’s like having free rein of a sweetshop.  Thankfully the utilities are displayed logically: monitoring, network discovery, diagnostic, and Cisco tools.  Try the SolarWinds Engineer’s Toolset now!

Download your fully functional trial copy of the Engineer’s Toolset v10

The ForEach Alias

It surprises those new to PowerShell that ForEach could also be an Alias for the cmdlet ForEach-Object.  Incidentally, it's to avoid this type of confusion I rarely use aliases in my scripts.

Get-Alias -definition ForEach-Object

Note 4: This research reveals not only 'Foreach', but also a second alias the percentage sign: %.

PowerShell's While Loops

My reason for mentioning the While loop here is to give perspective on the simple 'For' loop.

The 'While' loop is easy to master, and also flexible.  Each type of PowerShell loop has specific syntax rules; in the case of the 'While' loop there are only two elements (condition) and {Block Statement}.  As so often with PowerShell, the type of brackets is highly significant; (Parenthesis for the condition) and {curly braces for the command block}.

While Loop Example
The way that the loop works is that PowerShell evaluates the condition at the start of each cycle, and if it’s true, then it executes the command block.

Here is a simple PowerShell ‘while’ loop to calculate the 14 times table.

$i = 14; While ($i -le 200) { $i; $i +=14 }

# For ( $i = 14; $i -le 200; $i+=14 ) { $i }

Do While
The main contrast in the next example is the way the {block statement} comes first and the (control command) second, in this respect the 'Do While' Loop is the reverse of the For (and While) stepping method.

$i = 14; Do { $i; $i +=14 } While ($i -lt 200)

See more about 'While', and Do … While' Loops »

Summary: Differences Between PowerShell Loops

PowerShell provides a rich selection of techniques for looping.  On this page I have set out the differences between, 'For' and ForEach loops, and how they differ from piping data into the ForEach-Object cmdlet.

If you like this page then please share it with your friends


See more Windows PowerShell flow control examples

PowerShell Switch Statement  • PowerShell Real-life Techniques  • Free Permissions Analyzer

Differences between For, ForEach and ForEach-Object  • PowerShell Loops  • PowerShell Home

Conditional Operators   • Do While Loop  • PowerShell If Statement  • PowerShell Brackets

Please email me if you have a better example script. Also please report any factual mistakes, grammatical errors or broken links, I will be happy to correct the fault.