Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Do you want to learn what the PowerShell ForEach-Object cmdlet does? This guide teaches you all you need to know about this versatile cmdlet.
Overview
The Windows Operating System has 4 event logs. The screenshot shows that Windows 10 has Application, Security, Setup, and System event logs.

If you want to list the newest 5 Application event logs, you run the command below:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Get-EventLog -LogName Application -Newest 5
But what happens if you want to return the newest 5 logs in the Application, Security, Setup, and System event logs?
#1 Best Overall
- Book - powershell for sysadmins: workflow automation made easy
- Language: english
- Binding: paperback
One way to do this is to pipe the event log names into a ForEach-Object command. Then, within the ForEach-Object command, you’ll run the Get-EventLog command against each event log.
From the PowerShell perspective, the event log names are “input objects.” So, if I pipe the log names to a ForEach-Object command, the command will perform the Get-EventLog “operation” on the “input objects.”
So, if you need a definition, the ForEach-Object cmdlet performs an operation against each item in a collection of input objects (or items). In the example above, the ForEach-Object command performs the Get-EventLog “operation” on the collection of “input objects” (the four event log names).
Syntax of the ForEach-Object Cmdlet
The ForEach-Object cmdlet has three (3) syntaxes. Here they are…
ForEach-Object
[-InputObject <PSObject>]
[-Begin <ScriptBlock>]
[-Process] <ScriptBlock[]>
[-End <ScriptBlock>]
[-RemainingScripts <ScriptBlock[]>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
ForEach-Object
[-InputObject <PSObject>]
[-MemberName] <String>
[-ArgumentList <Object[]>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
ForEach-Object
[-InputObject <PSObject>]
-Parallel <ScriptBlock>
[-ThrottleLimit <Int32>]
[-TimeoutSeconds <Int32>]
[-AsJob]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
To make it easy for you to differentiate the syntaxes, I have boldened the parameters that are unique to each syntax. All other parameters that I did not bolden are common to the three syntaxes.
The first syntax of the PowerShell ForEach-Object cmdlet has four unique parameters – Begin, Process, End, and RemainingScripts. On the contrary, the second syntax has two unique syntaxes – MemberName, and ArgumentList.
Finally, the third syntax has four unique parameters – Parallel, ThrottleLimit, TimeoutSeconds, and AsJob.
Recommended Free Tools
In the next section, I will explain each syntax. I will not explain the WhatIf and CommonParameters as they are common to all cmdlets.
To learn about these two parameters, run the commands below:
Get-Help ForEach-Object -Parameter WhatIf Get-Help about_CommonParameters
Parameters of ForEach-Object
I have provided a detailed explanation of the ForEach-Object cmdlet parameters in the table below. The first table explains the two parameters common to the three syntaxes I explained in the last section.
Then, I will explain the parameters unique to each syntax in the subsequent three tables.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Parameters Common to all Syntaxes
The syntax below includes the parameters that are common to the three syntaxes of the ForEach-Object cmdlet.
ForEach-Object
[-InputObject <PSObject>]
[-WhatIf]
[-Confirm]
[<CommonParameters>]
The table below explains each parameter. I did not include WhatIf and CommonParameters as they’re NOT unique to the ForEach-Object cmdlet.
| Parameter Name | ForEach-Object Parameter Meaning/Notes |
|---|---|
| InputObject | Since the PowerShell ForEach-Object cmdlet performs an operation on each object in a collection of objects, you can use the InputObject parameter to specify the collection of objects. |
| Confirm | Whenever you see the Confirm parameter in a PowerShell cmdlet, it performs one task – prompts you for confirmation before running a cmdlet. So, if you specify the Confirm parameter in a ForEach-Object command, PowerShell will ask you to confirm that you want to run the command. |
Parameters Common to the First Syntax
In the syntaxes section of this guide, I showed you the three syntaxes of the ForEach-Object cmdlet. The syntax below has three unique parameters that are not available in the other two syntaxes.
ForEach-Object
[-Begin <ScriptBlock>]
[-Process] <ScriptBlock[]>
[-End <ScriptBlock>]
[-RemainingScripts <ScriptBlock[]>]
I have explained the parameters in the table below:
| Parameter Name | ForEach-Object Parameter Meaning/Notes |
|---|---|
| Begin | If you want ForEach-Object to run a command or script block before it processes any input objects, use the Begin parameter of the PowerShell ForEach-Object command to specify the command. |
| Process | After ForEach-Object runs the commands you specify in the Begin parameter, it proceeds to the Process parameter. Use the Process parameter to specify the operation you want PowerShell to perform on each input object. |
| End | Use the End parameter to specify a script block that runs after the PowerShell ForEach-Object cmdlet processes all input objects. |
| RemainingScripts | If you have any other script blocks you want ForEach-Object to run but couldn’t fit them into the Process parameter, use the RemainingScripts parameter to specify those additional script blocks. |
Parameters Common to the Second Syntax
As outlined in the syntax section of this guide, the second syntax of the PowerShell ForEach-Object cmdlet is…
ForEach-Object
[-MemberName] <String>
[-ArgumentList <Object[]>]
I have explained the two parameters in the table below:
| Parameter Name | ForEach-Object Parameter Meaning/Notes |
|---|---|
| MemberName | PowerShell objects have Properties and Methods. If you want ForEach-Object to get a property or call a method of an object, use the MemberName parameter to specify the Property or Method. |
| ArgumentList | If you specify a Method you want to call with the MemberName parameter, you may use the ArgumentList parameter to specify an array of arguments to the method you want to call. |
Parameters Common to the Third Syntax
The third syntax of the PowerShell ForEach-Object cmdlet is…
ForEach-Object
-Parallel <ScriptBlock>
[-ThrottleLimit <Int32>]
[-TimeoutSeconds <Int32>]
[-AsJob]
The table below explains each parameter…
| Parameter Name | ForEach-Object Parameter Meaning/Notes |
|---|---|
| Parallel | If you pipe input objects to ForEach-Object, by default, you run one command for each input object. However, there may be instances where you need to run multiple commands or script blocks for each input object. In this instance, ForEach-Object will process one script block, complete it and proceed to the next. But, you can specify the script block to be used for parallel processing of input objects. To do this, use the Parallel parameter. |
| AsJob | This is a Switch Parameter, meaning that it does not require any input. Specifying the AsJob in a PowerShell ForEach-Object command forces the parallel (see the Parallel parameter above) invocation to run as a PowerShell job. |
| TimeoutSeconds | You may want to limit how the command runs if you’re running multiple parallel tasks. To limit how long a parallel job runs, use the TimeoutSeconds parameter to specify a time in seconds. The default TimeoutSeconds for the PowerShell ForEach-Object command is zero (0). This means that, by default, ForEach-Object -Parallel can run indefinitely. |
| ThrottleLimit | Like the TimeoutSeconds parameter, this is a resource management parameter. As you can imagine, running multiple commands in parallel (simultaneously) can slow down the computer. If you want to limit the number of parallel commands running concurrently, use the ThrottleLimit parameter. The default number of parallel commands is 5. |
ForEach-Object Examples and Use Cases
The examples in this section show how to use ForEach-Object in real SysAsdmin applications.
1. List Logs in Multiple Event Logs at the Same Time
In the “Overview” section of this guide, I said that you could use the PowerShell ForEach-Object command to list the newest 5 logs in multiple event logs.
The fastest way to achieve this is to pipe the event log names into a ForEach-Object command. When you pipe objects into ForEach-Object, it returns each object as a pipeline variable, $_.
So, starting with my example command in the “Overview” section, to list the newest 5 events in the Application event log, I’ll run the command below…
Get-EventLog -LogName Application -Newest 5

However, if I want to perform the same task on the 4 event logs – Application, Security, Setup, and System – I’ll use the command below:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11"Application", "Security", "Setup", "System" | ForEach-Object { Get-EventLog -LogName $_ -Newest 5 }

2. Get the Index of Current Item in a PowerShell Loop
If you’re iterating through a collection of objects, you may need to get the current item’s index from the collection. I will start by saving the collection in a variable if I want to get the current item’s index in the loop.
Rank #3
$EventLogNames = "Application", "Security", "Setup", "System"
Then, I’ll pipe the $EventLogNames variable to a ForEach-Object command. Within the ForEach-Object loop, I will call the IndexOf Method as shown in the command below…
$EventLogNames | ForEach-Object {$EventLogNames.IndexOf($_) }
The command will list the index number of each item in the collection. As expected, the index of the first item in the collection is zero (0), the second is one (1), and so on.

To learn about the IndexOf Methos, read this article – How To Identify A PowerShell Substring Position With IndexOf And LastIndexOf Methods.
3. Filter PowerShell ForEach-Object Results with Multiple Conditions
In the last example, I showed you how to list the index of the items in a collection. What if I want to return all items with an index number greater than 2 and a log name of “System”?
This will require using ForEach-Object to iterate through the objects. Then, get the index of value and the names of the objects.
Then, use the IF statement to add the conditions that return the objects that meet the multiple conditions.
Let’s start by saving the objects in a variable, as we did in the last example.
$EventLogNames = "Application", "Security", "Setup", "System"
Next, I will save the index of the objects in a variable called $index. Finally, I will use the IF statement to add the multiple conditions.
Here is the command.
$EventLogNames | ForEach-Object {
$index = $EventLogNames.IndexOf($_)
IF (($index -gt 2) -and ($_ -match "System")) {
$_
}
}
And the result in PowerShell ISE. As we expected, the result returned “System.”

This is correct because, according to this command, “System” in this collection – Application, Security, Setup, and System – has an index of 3 – and 3 is greater than 2
$EventLogNames | ForEach-Object {$EventLogNames.IndexOf($_) }
4. Append a String to a Collection of Objects
In this example, I will show you how to use ForEach-Object to append the string “.com” to the names of websites. For this example, I want to use the Invoke-WebRequest command to return header information from Google.com, Microsoft.com, and Itechguides.com.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
However, I received the names Google, Microsoft, and Itechguides.
Rank #4
To run the Invoke-WebRequest command on these websites, I will pipe the names (without the .com) to ForEach-Object.
"Google", "Microsoft", "Itechguides" | ForEach-Object { }
Then, within the ForEach-Object block, I will use the command – $_ + ‘.com’ – to append “.com” to each website. To be able to ping the websites with the result of the last command, I’ll save them in a variable called $websites.
Here is the updated script…
"Google", "Microsoft", "Itechguides" | ForEach-Object {
$websites = $_ + '.com'
}
Finally, I will pipe $websites to another ForEach-Object block, and then within the child ForEach-Object block, I’ll use Test-Connection to ping the websites.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsHere is the command in the child ForEach-Object block.
$websites | ForEach-Object { Invoke-WebRequest $_ -Method Head }
Here is the full script…
"Google", "Microsoft","Itechguides" | ForEach-Object {
$websites = $_ + '.com'
ForEach-Object {
$websites | ForEach-Object { Invoke-WebRequest $_ -Method Head
}
}
}
To see the result, open PowerShell ISE, create a new script document, and copy the codes into the PowerShell ISE document. Finally, run the script.
Here is the result of the script in PowerShell ISE.

5. How to Use Begin, Process, End in ForEach-Object
In this last example, I’ll show you how to use the first parameter of the PowerShell ForEach-Object command. To refresh your mind, here is that syntax…
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
ForEach-Object
[-InputObject <PSObject>]
[-Begin <ScriptBlock>]
[-Process] <ScriptBlock[]>
[-End <ScriptBlock>]
[-RemainingScripts <ScriptBlock[]>]
When I explained this syntax earlier, I mentioned that you use the Begin parameter to specify a script block you want to run before ForEach-Object processes the input objects.
In this example, I want to list the 5 newest events in the System event log. However, I want to record when the command starts and when it ends.
The PowerShell ForEach-Object Begin Process End offers me a very simple way to achieve this.
Here is the idea…
Before I start listing the messages in the System event log, I will use the Begin parameter to display the current date and time. To do this, I will use the Get-Date command.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Get-EventLog -LogName System -Newest 5 | ForEach-Object -Begin {Get-Date}
Then, I will use the Process parameter block to display the newest messages in the System event log. Next, I’ll use the Write-Output command and its InputObject to display the messages ForEach-Object saved in $_.Message property.
Best Value
Get-EventLog -LogName System -Newest 5 | ForEach-Object -Begin {Get-Date} -Process {Write-Output -InputObject $_.Message}
Finally, I will use the End parameter block to display the current date and time (after ForEach-Object has displayed all the messages in the System event log.
Here is the final code.
Get-EventLog -LogName System -Newest 5 | ForEach-Object -Begin {Get-Date} -Process {Write-Output -InputObject $_.Message} -End {Get-Date}
The screenshot below shows the result of the above command. I highlighted the start time and the end time stamp.

Frequently Asked Questions
The forEach-Object cmdlet performs a specific operation or task on each item in a collection of items (or objects).
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →There are three types of ForEach commands in PowerShell.
Firstly, you have the ForEach-Object cmdlet. The easiest way to write command with the ForEach-Object cmdlet is to pipe the collection of objects to ForEach-Object.
Then, perform the task you wish to perform on each item in the collection.
Here is an example…
Get-EventLog -LogName System -Newest 5 | ForEach-Object {Write-Output -InputObject $_.Message}
The next type of ForEach command in PowerShell is the ForEach statement.
Here is the syntax of the ForEach statement –
ForEach ($ in $) {}
Finally, you have the ForEach() method, which Microsoft introduced in PowerShell 3.0.
The syntax of the ForEach() method is…
$.ForEach({ })
ForEach iterates a collection of items or objects and performs the same operation on each item in the collection.
So, ForEach picks the first item in the collection and performs the operation. Then, it returns to the collection, picks the next item, and performs the same operation.
ForEach object continues with the loop until it performs the operation on the last item in the collection.
To break a ForEach loop in PowerShell, use the Break statement. Literally, add the word Break when the ForEach loop meets your break condition.
You can use the split operator “-Split” or the split Method “.Split()” to split a string text into an array of strings or substrings. To learn more about how to use the split operator or method, read my article – PowerShell Substring: How to Extract A PowerShell Substring from a String.
Free tools Windows power users keep installed
One-click scans. No signup required.
Conclusion
The ForEach-Object command is a versatile PowerShell tool every serious PowerShell enthusiast must know how to use. You need this cmdlet to perform multiple tasks – from iterating through the items in a text file to looping through a CSV file.
You can use the ForEach statement in place of the ForEach-Object cmdlet. However, there are some scripting situations where the ForEach-Object cmdlet will be most suitable.
There is also the ForEach method, which is similar to the ForEach-Object cmdlet. Once again, you may still prefer the ForEach-Object cmdlet in some scripting scenarios.
I hope I helped you understand the ForEach-Object cmdlet and how to use it. If I succeeded, kindly let me know by responding to the “Was this page helpful?” question below.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsAlternatively, you may also ask a question about this topic.
Finally, if you love to read other hands-on PowerShell guides, visit our PowerShell & Windows Command Prompt Explained or Windows PowerShell How-To Guides pages
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.


I found the explanations and examples in this post incredibly helpful! PowerShell can be a bit daunting at first, but your clear breakdown of the ForEach-Object cmdlet made it much more approachable. Thank you for sharing these insights!