How Powershell Foreach, While, and Other Loops Work

Michael McConnell 09-01-2018

A crucial first step in learning programming is working with loops The Absolute Basics Of Programming For Beginners (Part 2) In part 2 of our absolute beginners guide to programming, I'll be covering the basics of functions, return values, loops and conditionals. Make sure you’ve read part 1 before tackling this, where I explained the... Read More . Thankfully, PowerShell continues to grow with your skills.


You can frame the existing commands you use every day inside loops to save time and effort. Your scripts do the heavy lifting while you do the important work of reading more articles on MakeUseOf!

Powershell ForEach Loops: The Door to Advanced Data Handling

ForEach is the alias for the ForEach-Object. (An Alias is merely a shortcut for a command in PowerShell.) This is a good time to talk about the way that PowerShell handles data.

Like most modern programming languages, PowerShell is object-oriented Where Did "Object Oriented" Programming Get Its Name From? Object Oriented isn’t just a random buzzword you hear in programming circles. There’s a reason behind the name - but what? Join me as I explore some of the fundamentals of programming concepts and explain... Read More . Everything in PowerShell is an object, meaning that even variables have extended properties and functions Powershell Cmdlets That'll Improve Your Windows Admin Skills Powershell is equal parts command line tool and scripting language. It gives you the ability to automate your computer via the same commands you use to administer it. Read More . That property is why you can set your searches to a variable, and end up with an array of the results.

$yourVar = Get-ChildItem *
foreach ($file in $yourVar){
  Your Steps

In some languages, processing this array would be a multistep process. First, getting the length and then counting up each step.

In PowerShell, you step through the array and perform the action on each one using ForEach. This saves you several lines of code, which is helpful if you’ve got a longer script. For example, the following is a small script that would use a couple of  Powershell ForEach loops. It creates a ZIP archive of all your files that you haven’t opened in 30 days.


Building a File Archive System Using ForEach Loops

Let’s break the steps down. You use Get-ChildItem to get all the files in the Documents folder. The environment variable What Are Environment Variables & How Can I Use Them? [Windows] Every now and then I'll learn a little tip that makes me think "well, if I known that a year ago then it'd have saved me hours of time". I vividly remember learning how to... Read More $env:USERPROFILE runs the script using the current profile. This variable is more portable than a hardcoded path. The results of that search are assigned to the variable $MyDocs. We then create our ForEach loop by having it step through each $Doc in $MyDocs.

$oldDocs = @()
$MyDocs = Get-ChildItem -Path "$($env:USERPROFILE)\Documents" -Recurse
foreach ($doc in $MyDocs){
  if($doc.LastAccessTime -lt $(Get-Date).addDays(-30)){
    $oldDocs += $doc
$ArchiveFolder = New-Item -Path "$($env:USERPROFILE)\Documents\$((Get-Date -Format MMddyy).toString())" -ItemType Directory
foreach ($doc in $oldDocs){
  Move-Item -Path $doc.FullName -Destination "$($ArchiveFolder.FullName)\$($doc.Name)" -Confirm $false
$source = $ArchiveFolder.FullName
$destination = "$($env:USERPROFILE)\Documents\$($ArchiveFolder.Name).zip"
Add-Type -AssemblyName ""
[io.compression.zipfile]::CreateFromDirectory($source, $destination)
if(test-path $destination){
  Remove-Item -Path $ArchiveFolder -Recurse -Confirm $false

Inside the loop, we check to see if each file’s LastAccessTime property is older than 30 days. We get this with the Get-Date cmdlet, and using the AddDays function with negative thirty. If it is, we add the file to the $myOldDocs array. After the file sort completes, we then take our completed array and create a zip file. This process is a little more complicated as it involves invoking a bit of .NET. Don’t worry if you don’t quite grasp it — you can steal the code from this TechNet help document.

To break down what’s happening here: We will move all of our old files to a new directory named for today’s date for older than 30 days. Once that folder builds, we have to create the ZIP archive of the same name. We’ll test to make sure that the archive succeeded and the .ZIP file is there, and then delete the new folder. Set this as a scheduled task to run once a month. You’ll save yourself a little space and keep your Documents folder clean.

While and Do While: Loops on Condition

If you want to run a loop only when a particular condition is met, you use a While loop. If you’re using a variable to track the count up, set that first.

  Your Steps

The problem is that if you aren’t using a counter, you might want your code to run at least once even if the test is true. This is the case with the example script below. So in those cases, you want to use a Do-While loop How Do-While Loops Work in Computer Programming Loops are one of the first control types you'll learn in programming. You probably know about while and for loops, but what does a do-while loop accomplish? Read More . The syntax is slightly different.

  Your Steps
}while(Conditional Statement)

Using these is not quite as obvious to a novice programmer. Doing typical day to day scripting, you may not run into them that often. Where they especially come in handy is to make a makeshift timer for testing the success of a process.

We’re going to build a quick script to reboot a remote machine and alert if it doesn’t come back up within 15 minutes. This scenario assumes it’s a home server or other machine that doesn’t reboot very often. Feel free to adjust the time if your computer typically comes up faster.

Reboot and Check: Using a Do-While Loop

This script is a bit simpler. First, you use the Restart-Computer command to reboot the remote machine. (We used a dummy IP here for the reboot commands, be sure to overwrite this with your computer’s DNS/IP). Then create the counter variable, i and set it to 0. Next, you have your Do loop with Start-Sleep stopping the script for 300 seconds (five minutes). A second command adds one to the counter.

Restart-Computer -ComputerName
  Start-Sleep -Seconds 300
  $i += 1
}while((!(Test-Connection -Quiet)) -or $i -gt 3)
if($i -gt 3){
  Write-Ouput "Remote Machine not responding, please check."
  Write-Output "Reboot Succeeded"

Then we have our While criteria. We use an Or test to ensure that a failure generates an alert. The alternative is the script looping endlessly waiting for the remote machine. To check for the machine, we are using the Test-Connection cmdlet. For simplicity, this is Ping for PowerShell. We add the parameter -Quiet which forces it to return True or False rather than the results of the packets. The second part of the Or statement checks if the counter is more than three.

Once the loop completes, we want to create the output. That means that we need to check our counter. This is a quick if/else statement. If it is greater than three, the script outputs that the remote machine isn’t responding. If it isn’t, it outputs that the reboot was successful.

Other Loops

There are two other kinds of loops available in PowerShell. They are somewhat related to the previous two loops, they just are not as commonly used. A For loop works similarly to the While example. You set all of your criteria in the evaluation, then set your cmdlets.

for($i = 0;$i -lt 10;$i++){
  Your Steps

Do Until loops are like Do While loops, you just change the While statement to Until. In the example script, it would be the same as far as behavior. It is a style choice, but the Do While is more versatile in other situations. So if you only remember one, Do While is more useful.


powershell foreach loops

PowerShell has help for each of these loops as well. You can get the help by adding about before the loop name in Get-Help. You can then see examples and other tips for each type. These should be helpful if you get stuck.

Continuing to Grow With You

At this point, you have most of the skills to start building robust scripts. Whether automating your home rig 15 Advanced Tasks PowerShell Can Handle in Windows 10 PowerShell is similar to the command prompt, but better. It's a powerful system administration tool. We have compiled 15 tasks, some simple, some complex, that benefit from the magic of PowerShell. Read More or saving time at work, loops help your scripts to do more. Combining these loops with error handling moves your scripting beyond the basics Handle PowerShell Errors Like a Boss With These Tips PowerShell error handling has four parts. Learn how to fix if errors and more in Microsoft PowerShell. Read More . This opens the door to more advanced languages.

What is a clever PowerShell script you’ve created using loops? Share it with us in the comments.

Related topics: PowerShell, Scripting.

Affiliate Disclosure: By buying the products we recommend, you help keep the site alive. Read more.

Whatsapp Pinterest

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Manny
    January 10, 2018 at 11:22 am

    Is the Windows shell case sensitive?

    • Michael
      January 16, 2018 at 3:48 pm

      It is not. Get-ChildItem and get-childitem are the same functionally. Even when comparing the strings ("I am a string") -eq ("i am a String") returns true.