Understanding PowerShell ForEach Loop and ForEach-Object

In Microsoft PowerShell scripting language, cmdlets are used to perform three operations: collect information, set information, and delete information. Apart from the cmdlets, PowerShell also provides the capability to process information more than once. There are two built-in PowerShell functions that most PowerShell admins use. They are ForEach Loop and ForEach-Object. The PowerShell ForEach Loop enables you to iterate through a set of items collected in a PowerShell variable. For example, using the Get-ADUser PowerShell cmdlet you can collect user information from Active Directory. If you needed to look at city property of each user before taking an action, you could use ForEach Loop. The ForEach-Object can be used to work with objects directly and mostly used in a pipeline as we’ll explain in this article. Let’s take a look at some of the examples in which ForEach Loop and ForEach-Object functions are used.

PowerShell ForEach Loop

PowerShell ForEach Loop
Our first example of using ForEach Loop is to check the city property of Active Directory users and then take an action. Let’s assume you would want to export users whose city property is set to “London” and then save the result in a CSV file. Here is the PowerShell script:

$CityReport = “C:\Temp\CityReport.CSV”
Remove-Item $CityReport -ErrorAction SilentlyContinue
$STR = “User Name, City”
Add-Content $CityReport $STR
$AllUsersNow = Get-ADUser –Filter * -SearchBase “OU=TestUsers,DC=TechGenix,DC=Com” -Properties *
Foreach ($ThisUser in $AllUsersNow)
$CityOfUser = $ThisUser.City
$ThisUserNow = $ThisUser.CN
IF ($CityOfUser -eq “London”)
$STRNew = $ThisUserNow+”,”+$CityOfUser
Add-Content $CityReport $STRNew

As you can see in the above script, we have created a variable named $CityReport that stores the path for CSV file where the report will be saved. Next, we are collecting all users from a specific organizational unit and storing the collected users with all properties in $AllUsersNow variable. Next, the ForEach Loop processing starts. In the ForEach Loop function we are checking the city property of the user and then using an IF condition, we are checking whether the city property holds the “London” value or not for the current user. If the user holds “London” as the value in the city property, the current username and city name values are added to the C:\Temp\CityReport.CSV file.

Another example of using ForEach Loop is to process information stored in a CSV file. Let’s assume you have a CSV file that holds username, city, and department values. You want to modify the user’s city and department properties from the CSV file. To do so, you will use the PowerShell script below:

$UserData = “C:\Temp\UserData.CSV”
$CSVFile = Import-CSV $UserData
Foreach ($ThisUser in $CSVFile)
$ModifyThisUser = $ThisUser
$NewDepartment = $ThisUser.Department
$NewCity = $ThisUser.City
Set-ADUser -Identity $ModifyThisUser -City $Newcity
Set-ADUser -Identity $ModifyThisUser -Department $NewDepartment

PowerShell ForEach Loop

As you can see in the above script, we have imported the contents of CSV file into $CSVFile variable and then using the ForEach Loop we are storing department and city values from the CSV file into $NewDepartment and $NewCity variables and then using the Set-ADUser PowerShell cmdlet we are updating the department and city values for the user.

In a nutshell, use PowerShell ForEach Loop when you need to process information more than once if you need to take an action on a specific item based on the property value of the item, and/or when you need to modify object information from a file.

Other than the ForEach Loop function, PowerShell also offers ForEach-Object. The ForEach-Object, as the name suggests, works directly with the objects and is mostly used in a pipeline. For example, as you can see in the command below, the Get-Process cmdlet retrieves all the processes on the local computer and ForEach-Object after the pipeline (|) processes the objects (process names), and then just displays the process name in the output window.

Get-Process | ForEach-Object {$_.ProcessName}

Similarly, if you needed to see the process name along with the process ID, you will execute this command:

Get-Process | ForEach-Object {$_.ProcessName, $_.ID}

Another example of using ForEach-Object is to get the length of all files in a directory. Let’s assume you would want to check the length of all files in C:\Temp folder. You will execute these commands:

$ThisDir = “C:\Temp”
Get-ChildItem $ThisDir | ForEach-Object –Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; ” ” }}

In the ForEach-Object PowerShell example below, you are collecting events from the Application Event Log and then saving the event message in a text file.

$AppEvents = Get-EventLog –LogName Application
$AppEvents | ForEach-Object –Process {Out-File –FilePath C:\Temp\AllAppEvents.TXT –Append –InputObject $_.Message}

Take it from here

So now you have an idea how to use the ForEach and ForEach-Object built-in PowerShell functions. The PowerShell ForEach Loop can be used to iterate through a set of items collected in a PowerShell variable and stored in a CSV file. The ForEach-Object function can be used to work with objects directly. The examples we provided using both ForEach Loop and ForEach-Object functions in this article should get you started and have you thinking of ways to use the commands in your work.

About The Author

6 thoughts on “Understanding PowerShell ForEach Loop and ForEach-Object”

  1. Could you show me what the .csv contents looks like, I can then understand how the $thisuser $modify.thisuser variables are created based on how the CSV is read. I don’t understand how you can create a variable that magically reads the right field (i.e. username for $thisuser). Thanks!

  2. ForEach is just an alias for ForEach-Object. The example using ForEach-Object works just as well with ForEach on its own.

  3. Is there a way to use the :label for breaking or continuing out of a ForEach-Object, for the purpose of nested ForEach-Object loops?

  4. Hi MV, Thanks for reading!

    You can always use “Exit” command to break the ForEach-Object or loop.


Leave a Comment

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top