PowerShell ForEach loop: Applications with examples

PowerShell ForEach loop: Applications with examples

What is a PowerShell ForEach loop?

A PowerShell ForEach loop or statement is a PowerShell contruct used in iterating through values in a collection of items. The PowerShell ForEach loop allows you to loop through a collection of items and perform a defined task (command) on each item. The key word here is “iterating”

When you iterate through a collection of items you literally take the first item in the collection performs an action. Then you go back, take the next and perform the same action. You continue to go back until you have gone through all the items in the collection. Think of PowerShell ForEach loop in this way.

For exsample, let’s say you have a crate of egg containing 12 eggs and you wish to break the eggs. Say you are required to break each egg with a knife such that you cut neatly through the centre of the egg.

You have to iterate through the crate which contains the collection of eggs. To achieve this, you take the first egg, cut it through neathly, keep it aside and take the next. This is what a PowerShell ForEach loop does.

To give a PowerShell example, lets run a very simple PowerShell command Get-ChildItem:

Get-ChildItem

The result of the command is shown below:

PowerShell-ForEach-Get-ChildItem

Notice that the Get-ChildItem command returned a collection of items. For this example, let’s concentrate on the ‘Name’ column. Assuming you wish to return only the items in the collection with a Name begginning with the letter ‘D’. You will need PowerShell ForEach loop to achieve this. We will come back to this example later in the article.

PowerShell ForEach loop Syntax

Before I introduce you to PowerShell ForEach loop Syntax, let me discuss a concept we will be using called ‘Variables’. A PowerShell variable stores values in units of memory. To create a variable in PowerShell, you asign the variable a name. The name begins with a dollar sign ($) followed by a text string. An example of a variable is $Info or $MyInfo. To learn more about PowerShell variables refer to about_Variables page. My PowerShell Tutorial Book Series also covers PowerShell variables in detail.

The syntax of a PowerShell ForEach loop is shown below.

ForEach ($item in $collection) {Perform a task based on a powershell command}

The syntax of a PowerShell ForEach loop starts with the word ‘ForEach’. The word ‘ForEach’ is then followed by brackets ‘()'; and finally ‘{}’ block. So, to aid your understanding of the PowerShell ForEach loop, lets have the syntax without any values:

ForEach ( ) { }

Whenever you want to script a PowerShell ForEach loop, simply start by typing ‘ForEach ( ) { }’ into your editor. Then populate the ForEach loop with values. This is one trick to PowerShell scripting. Always start from the basic and gradually add values! You can read a bit more about PowerShell scripts on the about_Scripts page.

Understanding the PowerShell ForEach loop syntax

In the PowerShell ForEach loop syntax, you will notice two variables enclosed in the bracket ‘()’. The second variable, $collection contains the colection of items. The first variable, $item is a variable assigned to each item in the collection as you iterate through the collection.

The construct of a PowerShell ForEach loop is very straight forward. It simply says: ForEach $item in ‘the’ $collection, perform the task(s) enclosed in the ‘{}’ block.

Following up from where we stopped, after we have typed ‘ForEach ( ) { }’, the next step will be to add a variable for each item in the collection; followed by the variable storing all the collections. Below is the syntax without any values.

ForEach ( ) { }

Let’s include the second bit in the ForEach loop

ForEach ($item in $collection) { }

Adding values within the ‘()’ PowerShell ForEach loop

I believe you have a good grasps of the ForEach loop contruct. I will move the knowledge further. Let me show you how you can add values within the bracket ‘()’ part of the PowerShell ForEach loop. Refer to the Get-ChildItem we ran earlier in the article.

Get-ChildItem

The result is shown below:

PowerShell-ForEach-Get-ChildItem

As I mentioned earlier, the Get-ChildItem returns a collection of items. To start with, let’s store the collection in a variable called $Results. The command accomplishes this.

$Results = Get-ChildItem

Creating a PowerShell variable is as simple as that! Variable name equals (=) Variable content. To confirm that the variable, $Results stored the information previously returned by the Get-ChildItem, execute the command below:

$Results

The command returns the results shown below.

PowerShell-ForEach-Get-ChildItem-Variable

So, the variable contains the collections. Before we construct our PowerShell ForEach loop, we need to assign a variable to each item in the $Results collection. Let’s call the variable $Result. Do not allow the similarity of the two variables confuse you.Our original collection was stored in $Results WITH ‘s’. The variable that will store each item contained in the $Results collection is $Result WITHOUT ‘s’. Note that you could name this variable anything.

Enough of talks. Let’s construct our PowerShell ForEach loop. Remember the first step? Construct the ForEach loop without any content. Can you do it on your own? See it below:

ForEach ($Result in $Results) { }

Running commands within the ‘{}’ block PowerShell ForEach loop

Let’s add commands to the the ‘{}’ portion of the PowerShell ForEach loop. Before we proceed, please refer to the result of the Get-ChildItem command once more. Earlier in the article, I said that if you wish to return only the items in the collection with a Name beginning with the letter ‘D’, the PowerShell ForEach loop will come in handly. Let’s see how this will work.

Before we proceed further, let me introduce you to another PowerShell concept called ‘IF’. You can get more information about ‘IF’ statements by referring to the about_If page. I will provide a quick overview of the ‘IF’ statement. An ‘IF’ statement runs a clode if a specified condition is met. The syntax of an ‘IF’ statement is shown below:

IF (condition1) {Exdecute the following codes} ELSEIF (condition2) {Exdecute the following codes} ELSE {Exdecute the following codes}

Providing a detailed explanation of the ‘IF’ statement is beyond the scope if this aritcle. Please refer to the about_If page for details.

Going back to our PowerShell ForEach loop example, we want to test the collections stored in the $Results variable for items with name starting with the letter ‘D’. To achieve this, we simply add an ‘IF’ statement within the ‘{}’ block of the PowerShell ForEach loop. Below is where we left off the command earlier:

ForEach ($Result in $Results) { }

To proceed, add an ‘IF’ statement within the ‘{}’ as shwon below.

ForEach ($Result in $Results) { IF($Result -LIKE 'D*') {} }

Notice that I have not finished the ‘IF’ statement block? I intentionally left out adding anything within the ‘{}’ portion of the ‘IF’ command block. I want you to understand the logic behind anything I add. Look at the command above and compare it with the previous command. The difference is “IF($Result -LIKE ‘D*’) {}” placed within the ‘{}’ block of the PowerShell ForEach loop construct.

Now that we have added a condition to the ‘IF’ statement, we want to tell the ‘IF’ statement what to do if that condition is TRUE. This is achieved by adding a command within the ‘{}’ block of the ‘IF’ statement. Here you go!

ForEach ($Result in $Results) { IF( $Result.Name -like 'D*') {$Result } }

Boom! The command returned only items in the collection with names as shown below. What we did was to simply return items in the $Result variable if the condition in the ‘IF’ statement is met.

PowerShell-ForEach-Get-ChildItem-If-result

You can apply this principle in any scripting condition requiring you to use the PowerShell ForEach loop!

Running commands directly to create a collection in a PowerShell ForEach loop

I started the previous section by storing the collections obtained from the Get-ChildItem command into a variable called $Results. We will be able to achieve the same outcome without storing the collections in a variable. We will run the Get-ChildItem command directly in place of the $Results variable. Let’s go back to the original state of command as shown below:

ForEach ($Result in $Results) { }

Next, let’s replace the $Results variable with the Get-ChildItem command

ForEach ($Result in Get-ChildItem) { }

The logic already explained earlier in this article applies. The variable, $Result is assigned to each item in the collection returned by the Get-ChildItem command.Just like we did earlier, lets introduce the ‘IF’ statement block.

ForEach ($Result in Get-ChildItem) { IF( $Result.Name -like 'D*') {$Result } }

We have exactly the same result as before!. One last word before we move on. The reason you might want to store the collection in a variable rather than run the command directly is because some command may be too long to manage conveniently within the PowerShell ForEach loop construct. In such cirstance, you are better off running the command outside the PowerShell ForEach loop and storing it in a variable.

PowerShell-ForEach-Get-ChildItem-If-result-direct

 

Practical example of the use of PowerShell ForEach loop

In the last section of this article, I will give you real life, system admin application of the PowerShell ForEach loop. In this example, I will show you how I used the ForEach loop construct in my Get-InactiveADUsers (Function available on the Microsoft script Gallery).

The Get-InactiveADUsers function reports users that have not logged on to an Active Directory domain in X days. The Get-InactiveADUsers Function has a parameter called ‘SearchBase’. It allows a user to specifiy the Active Directory container to search for ‘inactive’ users – users that have not logged on for ‘X’ number of days.

The ‘SearchBase’ parameter specify the user-friendly name of the Active Directory container. But my command that searches for users requires the distinguishedName (DN) of the object. My first task is to take the name provided by the user via the ‘SearchBase’ parameter and convert it to the DN format. The command below achieves this purpose (Copied command as shown in line 101 of the Get-InactiveADUsers function).

$SearchLoc = (Get-ADObject -LDAPFilter "(Name=$SearchBase)" -Properties name -server $ADServer).distinguishedName

You should be able to note that I stored the result of the Get-ADObject command in a variable called $SearchLoc. But there is one more problem. There might be more than one Active Directory container in the AD forest with the same name. I will need to loop through the $SearchLoc collection with our famous PowerShell ForEach loop. To loop through the $SearchLoc variable, I executed the command below:

ForEach ($DN in $SearchLoc) { $Users = Get-ADUser -Server $ADServer -SearchBase $DN -Filter * -Properties lastlogondate | Where-Object {($_.lastlogondate -le $LastLogonDate) }

Just like our previuos example, the individual items in the $SearchLoc variable is stored in the $DN variable. For the avoidance of doubt, the variable $ADServer is also a parameter in the Get-InactiveADUsers function. The information is provided by the user. The function has some other commands but you get the gist. To get the function, download it from the link provided in the “References and further reading” section below.

References and further reading on PowerShell ForEach loop

Leave a Reply