Skip to the main content.

ScriptRunner Blog

Getting Loopy: An Introduction to PowerShell Loops

Table of Contents

Post Featured Image

Loops are the lifeblood of most programming languages, and they play an integral role in any code. Controlling the execution of a program to iterate over a collection of items is an extremely common task.

PowerShell is no different and offers a number of different loop options and ways to control the code execution. This article will give an overview of different types of PowerShell loops and what you can achieve with them.

 

So what loops are available in PowerShell?

  • For
  • ForEach-Object
  • Foreach
  • While
  • Do-While
  • Do-Until

Some of these loops are traditional in how they function, while others such as ForEach-Object are unique to PowerShell and how the PowerShell object pipeline works. All of them have their place and are useful in different ways. With that being said, let’s jump into PowerShell loops!


For-Loop

The For-loop is one of the first loops that most programmers learn how to use. It is typically used to step through a collection a set number of times and run the defined code on each iteration. The For-loop requires that an iterator variable be defined with an initial value, a condition to meet that will end the loop, and how to increase or decrease the iterator variable each time the loop is run. Here’s an example:
For ($i = 1; $i -LE 5; $i++) {
		$i * 2 
		}

# Output 2, 4, 6, 8, 10

This simple loop operates on the $i variable and as you can see simply multiplies the value of the iterator by 2 each time the loop is run.


Foreach-Loop

The object pipeline is unique to PowerShell. It allows for higher flexibility with manipulating the objects that are iterated over, but the trade-off is often slower performance.

To counteract that, the foreach-statement in PowerShell allows front-loading all items of a collection of objects that should be iterated over instead of streaming those objects in like ForEach-Object does. This comes at the cost of higher memory usage but increased performance.

$Array = 1..5 

Foreach ($Number In $Array) {
		$Number
		} 
		
# Output 
1, 2, 3, 4, 5

A useful ability is that Foreach can be used with a cmdlet that returns a collection of objects. One of the most common examples of this is using Get-ChildItem to return a collection of files.

 

$i = 1 Foreach ($File in Get-ChildItem) {
"File {0}: {1}" -F $i, $File.FullName $i++
}
# Output
File 1: C:\Test\File1.txt
File 2: C:\Test\File2.txt

Another very useful feature is the ability to skip a number by using the special function of $foreach.MoveNext(). This allows you to skip the current loop and move to the next value. In this case I am sending that output to Out-Null as the default returned value is true which I do not want to display.
$Array = 1..20
Foreach ($Number In $Array) { 
		If ($Number % 2) {
		$Foreach.MoveNext() | Out-Null 
		} 
		$Number 
		} 
		
# Output
1, 3, 5, 7, 9, 11, 13, 15, 17, 19

ForEach-Object-Loop

As described in the Foreach-loop, ForEach-Object expects a stream of objects from the PowerShell pipeline. Not quite as fast as Foreach, this method allows for some additional functionality to help make ForEach-Object very flexible. There are two main reasons for this:
  • Ability to use Begin, Process, and End blocks
  • Stream resulting objects to cmdlets further down the pipeline
$Array = @("Item4", "Item2", "Item1", "Item3") 
$Array | ForEach-Object {
		"{0}.{1}" -F $_, "txt" 
		} | Sort-Object 
		
# Output Item1.txt, Item2.txt, Item3.txt, Item4.txt

As mentioned above, the other useful feature is the ability to define a Begin and End block, along with the standard Process block.

$Array = @("Item4", "Item2", "Item1", "Item3")
$Array | ForEach-Object { $i = 0 } {
		"File {0}: {1}.{2}" -F $i, $_, "txt" 
		$i++ 
		} { Write-Host "Files Count: $i" } 
		
# Output 
File 0: Item4.txt 
File 1: Item2.txt 
File 2: Item1.txt 
File 3: Item3.txt 
Files Count: 4

 

While-Loop

The while-loop is a simple loop that continues while the condition is true. This also means that you can potentially create infinite loops.
While ($Value -NE 3) { 
		$Value++ 
		Write-Host "Value: $Value" 
		} 

#Output 
Value: 1 
Value: 2 
Value: 3

An example of an infinite loop is by simply having a condition that will always evaluate to true. You can do this by the following code.

While ($True) { 
		"This will run forever!" 
		}

#Output
This will run forever!

Do-While-Loop

Similar to a while-loop, the Do-While construct simply prepends a scriptblock to a while-loop which means that the script is run at least a single time, even if the while-loop immediately evaluates to false on the next or first run.
Do { 
		Write-Host "This will display no matter what" 
		} While ($False) 
		
# Output
This will display no matter what

Do-Until-Loop

Finally, the Do-Until statement is essentially the inverse of Do-While. Run a scriptblock at least one time until the condition becomes true.
Do { 
		Write-Host "This will display no matter what" 
		} Until ($True) 
		
# Output
This will display no matter what

Conclusion

As you can see there are many useful ways that loops can be used and combined in PowerShell to make ever more powerful scripts. Mastering loops is guaranteed to increase the utility of PowerShell and how it can assist in automating even the most complex of tasks.

A whole range of examples can be found in the ScriptRunner ActionPacks. These ready-to-use and free PowerShell scripts allow you to quickly and easily implement numerous use cases in the area of systems administration and IT operations management.

 

Related posts

3 min read

ScriptRunner now available in the Microsoft Azure Marketplace

6 min read

Managing Microsoft Exchange with PowerShell

2 min read

VMUG Webcast: Mastering VMware Management with PowerCLI

About the author: