Windows PowerShell Loops

Windows PowerShell Loops

Automating repetitive tasks is what scripting is all about.  Therefore, each scripting language needs at least one method for cycling, or looping through a block of instructions.  PowerShell provides a rich variety of looping techniques.  However, because loops can go spectacularly wrong, I recommend you test a simple PowerShell ‘ForEach’ loop before graduating to more complex constructions in your production scripts.

Types of PowerShell Loop


Examples of the PowerShell Foreach Loop

The PowerShell ‘Foreach’ loop is more complex, and has more arguments than the ‘for’ and ‘Do While’ loops.  The key feature is that the loop interrogates an array, known as a collection.  It then applies a {Statement Block} to each iteration.  In addition to the position and the type of bracket, observe the tiny, but crucial keyword – ‘In’.

The secret of understanding PowerShell’s loops is to absorb each element of this syntax:
Foreach ($item in $array_collection) {command_block}.

Example 1: PowerShell Foreach with Pure Math

Here are examples of the ForEach loop, note the word 'In'.

# Simple PowerShell ForEach statement
ForEach ($number in 1,2,3,4,5,6,7,8,9,10) { $number * 7}

# PowerShell Foreach Example
ForEach ($number in 1..10 ) { $number * 7}

$NumArray = (1,2,3,4,5,6,7,8,9,10)
ForEach ($number in $NumArray ) { $number * 7}

ForEach ($number in 1,2,3,4,5,6,7,8,9,10) { $number * 7}

$NumArray = (1..10)
ForEach ($number in $numArray ) { $number * 7}

Learning Points

Note 1:  By creating these five variations, my aim is to give you both perspective and experience of the pure, but simple PowerShell ForEach statement.

Note 2:  (1..12) is a convenient method of representing a sequence.

Example 2: PowerShell Foreach to Display Files

In Examples 2a and 2b we are going to make the transition from the explicit ($Item in Collection) {Block Statement} to:
Input stuff using Get-ChildItem, then pipe (|) the output into a {Block Statement}.

Get-ChildItem is just the vehicle for us to investigate aspects of the PowerShell ForEach loop.  I chose the root of the C: drive simply because this script will work without modification on 99.9% of computers.

Example 2a Explicit Foreach Get-ChildItem
Using the ForEach Loop

# PowerShell Foreach File Example
Foreach ($file in Get-Childitem C:\)

Example 2b Foreach-Object Piping | Directly Into the {block statement}
This example employs the ForEach-Object cmdlet, one difference is that it can accept piping, instead of using ($Item in $Collection) clause.

# PowerShell Foreach File Example
$Path = "C:\Windows\System32\*.dll"
Get-ChildItem $Path | Foreach-Object {
Write-Host $_.Name

Learning Points

Note 3: To help you modify my scripts to suit your project I have introduced a $Path variable.

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

Example 3a: A Complex Foreach Example

This pair of examples are just like the above, but introduce slightly more complex scripting.  Example 3a contains Foreach with a ($Item in Collection) clause; please contrast with example 3b which exploits the ability of ForEach to receive input via the pipe (|).

# PowerShell ForEach loop to display files in C:\Program files
$Path = "C:\Program Files\"
"{0,10} {1,-24} {2,-2}" -f `
" Size", "Last Accessed", "File Name "
Foreach ($file in Get-Childitem $Path -recurse -force)
{If ($file.extension -eq ".txt")
    "{0,10} {1,-24} {2,-2}" -f `
    $file.length, $file.LastAccessTime, $file.fullname

Example 3b Foreach-Object piping | directly into the {block statement}

# PowerShell ForEach-Objcet piping into block statement
$Path = "C:\Program Files\"
Get-Childitem $Path -recurse -force |
Foreach-Object {
If ($_.extension -eq ".txt")
{Write-Host $_.fullname

Note 4: This example uses the same ‘If clause’ as example 3a, its purpose is to filter just .txt files. See PowerShell 3.0 Foreach-Object.

Example 4a: PowerShell Foreach Loop With WMI

Once again, observe the basic structure: Foreach (x in y) {script block}.  Where you have more than one drive you need a loop, in this case the ForEach loop.

Basic Example

$disk= Get-WmiObject Win32_LogicalDisk
Foreach ( $drive In $disk ) { "Drive = " + $drive.Name}

Example Incorporating Extra Maths

# Foreach example to display the partitions size [GB]
$disk= Get-WmiObject Win32_LogicalDisk
"Drive Ltr: Size [GB]"
Foreach ( $drive in $disk ) { "Drive = " + $drive.Name + `
" Size = " + [int]($drive.Size/1073741824)}

Example 4b: Another Simple Foreach Using Get-Process

Here is an example using Get-Process.  In essence this simple script filters the running processes.  Please feel free to modify.  Once again, note the tiny word ‘in’.

# PowerShell example listing processes beginning with Task*
Foreach ($T In Get-Process Task*)

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

Example 5: Active Directory

This example conforms to the PowerShell ForEach (condition) {Code Block}; however, there is a preamble of 16 lines where the script connect to Active Directory.  Moreover, the {Code Block} is spread over several lines.

N.B. Find $Dom on line 7 and change the value to that of your domain, including the extension.

# ForEach_AD.ps1
# Illustrates using PowerShell ForEach loop to interrogate AD
# IMPORTANT change $Dom ‘value’
# Author: Guy Thomas
$Dom = ‘LDAP://DC=YourDom;DC=YourExt’
$Root = New-Object DirectoryServices.DirectoryEntry

# Create a selector and start searching from the Root of AD
$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root

# Filter the users with -Like "CN=Person*". Note the ForEach loop
$adobj= $selector.findall() |
Where-Object {$ -Like "CN=Person*"}
ForEach ($person In $adobj)
      Write-host "First name: $($prop.givenname) " `
      "Surname: $($ User: $($"
write-host "`nThere are $($adobj.count) users in the $($ domain"

Learning Points

Note 5: The backtick ` on its own means word-wrap.  `n means new line and `t means tab.

Guy Recommends: Free WMI Monitor for PowerShellSolarwinds Free WMI Monitor for PowerShell

Windows Management Instrumentation (WMI) is one of the hidden treasures of Microsoft’s operating systems.  Fortunately, SolarWinds have created a Free WMI Monitor so that you can discover these gems of performance information, and thus improve your PowerShell scripts.

Take the guess work out of which WMI counters to use when scripting the operating system, Active Directory, or Exchange Server. Give this WMI monitor a try – it’s free.

Download your free copy of WMI Monitor

PowerShell Loop Output Trick

I have not found it possible to pipe input into loops.  Obtaining output was nearly as difficult, however, I have discovered this trick to assign the output to a variable, which we can then manipulate.

$NumArray = (1..12)
$(Foreach ($number In $NumArray ) { $number * 7}) | set-variable 7x
# Option research properties by removing # on the next line
# $7x | Get-Member

Dejan Milic’s Method (Better)

$NumArray = (1..12)
$7x = @()
Foreach ($number In $NumArray ) { $7x+=$number * 7}

/\/\o\/\/’s  Method (Fantastic)

$7x = 1..12 |% {$_ * 7 }

I (Guy) envy /\/\o\/\/’s ability to write tight code.  That % sign means ‘ForEach’. If you (readers) see anything on the internet by /\/\o\/\/, then you can be sure that it’s top draw code.


PowerShell For Loop (Also know as the 'For Statement')

One use of PowerShell's plain, simple ‘For loop’ is to iterate an array of values and then work with a subset of these values.  Should you wish to cycle through all the values in your array, consider using a ForEach construction.

Here is the syntax: For (<init>; <condition>; <repeat>) {<command_block>}


For ( $i = 7; $i -le 84; $i+=7 ) { $i }

Note 6: There is no 'In' syntax in this simple loop.

PowerShell While Loops

The ‘While’ loop is the easiest to master, and also the most 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}. 

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, and then display, the 7 times table.

# PowerShell While Loop
$i =7
While ($i -le 85) { $i; $i +=7}

Learning Points

Note 7: $i is a variable set to 7.  Remember, the mission was to create the seven times table.
Note 8: Observe the two types of bracket (while) {Block Calculation}
Note 9: -le means less than or equals.  (Other comparators are: -eq and -gt)
Note 10: +=7 increments the variable $i by seven on each loop.

Alternatively, we could use a semicolon to join the two statements to form one line.
$i =7;  While ($i -le 85) { $i; $i +=7 }.

Do While Loop

In the ‘Do … While’ loop, PowerShell checks the (condition) at the end of each loop.  One feature of the ‘Do While’ loop is that the {Command Block} is always executed at least once, this is because the ‘While’ comes after the ‘Do’.

$i = 7; Do { $i; $i +=7 } While ($i -le 85)

Note 11: Without the semicolon it would need two lines thus:

$i = 7
Do { $i; $i +=7 } While ($i -le 85)

Do Until
There is a variation of this style of loop, ‘Do .. Until’.  The layout of the components is the same as ‘Do While’, the only difference is that the logic is changed from, do while condition is true, to, do until condition is true.

$i = 7; Do { $i; $i +=7 } Until ($i -gt 85)

For Even More Information about Foreach Loops Check About_Foreach

Get-Help about_Foreach

Note 12: There is also a Foreach-Object Cmdlet

Get-Help ForEach-Object

See more about Do While, and Do Until Loops »

Summary of PowerShell Loops

PowerShell supports a variety of different loops, for example, ‘While’ and ‘Foreach’.  The secret of understanding the PowerShell loop is to study the type of bracket.  For example when defining the constructions elements, (use parenthesis) for the condition and {use braces} for the command block.  Take the time to master loops, and thus automate your repetitive tasks.

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.