Skip navigation
blue_gears.jpg Getty Images

How To Use a For Each Loop in PowerShell

For Each loops let you perform an action against multiple items in PowerShell. Read these step-by-step instructions to learn how to use a For Each loop.

In PowerShell, a For Each loop (sometimes referred to as a ForEach-Object loop) is useful when you need a script to perform an action against multiple items. In this article, I will explain how a ForEach loop works.

Preparing a For Each Loop

Before you can create a For Each loop, you need a dataset to use the loop on. This dataset can be just about anything, but the data is normally contained within a variable. In addition to a variable representing the entire dataset, you will also need a variable that represents a single item within the dataset.

To give a more concrete example, let’s suppose that you have a Hyper-V Server that contains lots of virtual machines (VMs), only some of which are powered up at the moment. Let’s say you want to use PowerShell to shut down any virtual machines that are running so that you can take down the Hyper-V host server for maintenance.

The first thing that you would want to do in this situation is get a list of the running VMs. Use this PowerShell cmdlet to do so:

Get-VM | Where-Object {$_.State -eq ‘Running’}

Figure 1 shows this command and its output. It is worth noting that in the interest of keeping things simple, I am running the command directly on the Hyper-V server. In the real world, you would likely use the -ComputerName parameter to direct the command toward a remote server.

Brien PoseyPowerShell sessions shows a list of the running virtual machines on the local Hyper-V server

Figure 1. I am using the Get-VM cmdlet combined with the Where-Object cmdlet to get a list of the running virtual machines on the local Hyper-V server.

It is in fact possible to shut down the virtual machines that are running without using a For Each loop. All you would do is to use the command listed above and append the pipe symbol and the Stop-VM cmdlet. However, since the purpose of this article is to teach you how a For Each loop works, let’s pretend that the direct approach is not an option.

As I mentioned above, the dataset that you supply to the loop usually must be stored in a variable. In this case, I am going to create a variable called $ListOfVMs and set the variable equal to the command shown in Figure 1.

As you can see in Figure 2, typing the variable’s name reveals that the variable contains the list of virtual machines currently running. Although I am using virtual machines in this example, keep in mind that you can create a For Each loop to go with a variety of data types.

Brien PoseyPowerShell session shows list of virtual machines written to a variable named $ListOfVMs

Figure 2. I have written the list of virtual machines to a variable named $ListOfVMs.

Now that there is a variable that represents the entire dataset ($ListOfVMs), you will need a variable that can represent a single item from the dataset. I will call this variable $VM because it will represent a single virtual machine from the list of virtual machines.

Set up the For Each Loop

We now have everything we need to set up a For Each loop.

Here is what the loop looks like:

ForEach ($VM in $ListOfVMs){
Stop-VM $VM.Name

As you can see, the loop consists of three lines of code.

The first line of code declares the loop. This loop tells PowerShell that we want to perform an action for each virtual machine ($VM) in the list of running virtual machines ($ListOfVMs).

The action that is being performed must appear between brackets. In this case, only a single action (Stop-VM $VM.Name) is being performed, but in the real world, it is common to have multiple lines of code appear between the brackets, particularly when performing more complex tasks. Stop-VM is the actual shutdown command, while $VM.Name supplies the name of the virtual machine that is currently being processed by the loop. You can see what the command looks like in Figure 3.

Brien PoseyPowerShell session shows three lines of code condensed into a single line

Figure 3. I have condensed the three lines of code into a single line.


Incidentally, there is a shortcut to this technique that eliminates the use of the $VM variable. You simply call the $ListOfVMs variable, then pipe it directly into the ForEach command. Here is what the command looks like:

$ListOfVMs | ForEach {Stop-VM $_.Name}

As you can see, this command works very similarly to the other command. There is a big difference, however: Because I did away with the $VMs variable, I can’t use $VM.Name to specify the name of the VM that is to be shut down. Instead, I am using $_.Name to supply the virtual machine name. You can see what the command looks like in Figure 4.

Brien PoseyPowerShell session shows shortcut

Figure 4. You can take shortcuts when using the ForEach command.

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.