3

I have been attempting to execute parallel commands on data (such as a list of Server Names) that is imported via CSV and called by ForEach-Object. I have found that foreach has a parallel method but it appears that ForEach-Object does not. I am concerned about good performance as I hit multiple servers to read log data, and have the following options:

1) PowerShell Workflow 
2) PowerShell Background Job 
3) Invoke-Command

When I tried option 3, it failed as I tried to send arguments via -ArgumentList, but it didn't seem to like the variables I was pushing from the CSV in the form of:

$($_.'CSVColumnValue')

Is it possible to execute commands in parallel using ForEach-Object, and if so, what is the recommended method to achieve this?

2
  • 1
    please add your code to your question, otherwise it's difficult to give advice Commented Mar 5, 2016 at 12:25
  • 1
    You also may want to look at Invoke-ScriptAsync which uses RunSpace Pools to quickly run a script against a list of servers. Commented Mar 13, 2016 at 2:01

2 Answers 2

4

There is no such thing as 'ForEach-Object -Parallel' since it is performed in the pipeline. Check Erik Meijer and Jeffrey Snover at MSDN Channel 9; those folks are gettin' nitty-gritty on the pipeline of PowerShell. It's a vid from 2008, lasts over an hour, but still... excellent on how the pipeline works.

The 'ForEach -Parallel' is a construct and not a pipeline cmdlet. It is part of the Workflow module and introduced in Windows PowerShell 3.0.

Compare:

$Items = 1..42
ForEach -Parallel ($Item in $Items) {
 $Item
}

With:

1..42 | ForEach-Object -Process { $_ }
Sign up to request clarification or add additional context in comments.

1 Comment

So it's not possible to use any of the other constructs from ForEach-Object such as -Begin {} then?
1

As far as invoke-command goes, you would need to use the 'using' scope to access local variables:

$a = 'hi there'
invoke-command comp001 { echo $using:a }

Or to pipe something in:

1,2,3 | invoke-command comp001 { echo $input } 

-argumentlist only works if there's a param defined in the scriptblock. The docs aren't good on this point.

$a = 'hi'
invoke-command comp001 { param($a) echo $a } -ArgumentList $a

Unless you use args:

invoke-command comp001 { echo $args[0] } -ArgumentList $a

Powershell 7 preview 3 actually has a multi-thread "foreach-object -parallel":

 1..5 | ForEach-Object -Parallel { sleep 10; 'done' }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.