PowerShell ForEach-Object Explained With Examples

Photo of author

By Victor Ashiedu

Published

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.

To make this an interesting read, I have sectioned the guide. In the first section, I will introduce you to the ForEach-Object cmdlet.

This will be followed by the syntaxes of the PowerShell ForEach-Object cmdlet. Then, to help you understand the syntaxes of this cmdlet, I’ll explain the parameters in section three of this guide.

After you have learned about this versatile cmdlet, you’ll cement your knowledge with some of my examples. Finally, you can read frequently asked questions about the ForEach-Object cmdlet in my FAQ section.

Overview

The Windows Operating System has 4 event logs. The screenshot shows that Windows 10 has Application, Security, Setup, and System event logs.

PowerShell ForEach-Object: Overview

If you one to get the newest 5 Application event logs, you run the command below:

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?

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 PowerShell ForEach-Object

Syntax Of PowerShell ForEach-Object

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.

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 PowerShell 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.

If some of the parameters do not make sense, try to grasp as much as you can. When you finish and proceed to the examples section of this guide, I’ll use the examples to explain some of the syntaxes and parameters.

The ForEach-Object 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 NameForEach-Object Parameter Meaning/Notes
InputObjectSince 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.
ConfirmWhenever 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.

The ForEach-Object 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 NameForEach-Object Parameter Meaning/Notes
BeginIf 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.
ProcessAfter 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.
EndUse the End parameter to specify a script block that runs after the PowerShell ForEach-Object cmdlet processes all input objects.
RemainingScriptsIf 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.

The ForEach-Object 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[]>]
As with the syntax in the first syntax, the syntax above has only the two parameters unique to this syntax.

I have explained the two parameters in the table below:

Parameter NameForEach-Object Parameter Meaning/Notes
MemberNamePowerShell 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.
ArgumentListIf 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.

The ForEach-Object 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 NameForEach-Object Parameter Meaning/Notes
ParallelIf 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.
AsJobThis 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.
TimeoutSecondsYou 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.
ThrottleLimitLike 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.

PowerShell ForEach-Object Examples

PowerShell ForEach-Object Examples

The examples in this section show how to use ForEach-Object in real SysAsdmin applications.

How To Use ForEach-Object To 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
How To Use ForEach-Object To List Logs In Multiple Event Logs At The Same Time

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:

To run this command successfully, you need to run PowerShell as administrator.
"Application", "Security", "Setup", "System" | ForEach-Object { Get-EventLog -LogName $_ -Newest 5 } 

How To Use The ForEach-Object Command To 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.

$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.

How To Use The ForEach-Object Command To Get The Index Of Current Item In A PowerShell Loop

To learn about the IndexOf Methos, read this article – How To Identify A PowerShell Substring Position With IndexOf And LastIndexOf Methods.

How To 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($_)  }

How To Use PowerShell ForEach-Object To 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.

However, I received the names Google, Microsoft, and Itechguides.

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.

Here 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.

How To Use PowerShell ForEach-Object To Append A String To A Collection Of Objects

How To Use PowerShell ForEach-Object Begin Process End

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…

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.

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.

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

Frequently Asked Questions About PowerShell ForEach-Object
1. What Does ForEach-Object Do?

The forEach-Object cmdlet performs a specific operation or task on each item in a collection of items (or objects).

2. How Do You Write A ForEach In PowerShell?

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 ($<item> in $<collection>) {<statement lists>}

Finally, you have the ForEach() method, which Microsoft introduced in PowerShell 3.0.

The syntax of the ForEach() method is…

$<collection>.ForEach({ <statement lists> })

3. How Does ForEach Work In PowerShell?

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.

4. How Do I Break A ForEach Loop In PowerShell?

To break a ForEach loop in PowerShell, use the Break statement. Literally, add the word Break when the ForEach loop meets your break condition.

5. How Do I Split A String Into An Array In PowerShell?

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.

My Final Thoughts

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 helped you understand the ForEach-Object cmdlet and how to use it. If I succeeded, kindly spare two minutes to share your experience with us at [discourse_topic_url].

Alternatively, you may also ask a question about this topic at [discourse_topic_url].

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.

References And Further Reading

  1. ForEach-Object (Microsoft.PowerShell.Core) – PowerShell | Microsoft Docs
  2. about Foreach-Parallel – PowerShell | Microsoft Docs
  3. How to execute Parallel Processing with PowerShell? | Triveni Global Software Services LLP
  4. How To Identify A PowerShell Substring Position With IndexOf And LastIndexOf Methods
  5. Powershell scripting using where-object – Stack Overflow
  6. powershell – How to append strings to other strings in a data set? – Stack Overflow
  7. PowerShell Substring: How to Extract A PowerShell Substring from a String (www.itechguides.com)
  8. [discourse_topic_url]
We go the extra mile to deliver the highest quality content for our readers. Read our Content Writing, Content Review, and Anti-Plagiarism policies to learn more.

About the Author

Photo of author

Victor Ashiedu

Victor is the founder of InfoPress Media, publishers of Ilifeguides and Itechguides. With 20+ years of experience in IT infrastructure, his expertise spans Windows, Linux, and DevOps. Explore his contributions on Itechguides.com for insightful how-to guides and product reviews.

Related Articles

Get in Touch

If this article does not meet your expectations, kindly let us know. We have various ways you can get in touch with us:

  1. Respond to "Was this page helpful?" above
  2. Leave a comment with the "Leave a Comment" form below
  3. Email us at [email protected] or via the Contact Us page.

Leave a comment

Send this to a friend