4
votes

What I want:

I have a script, which copies CAB-Files to over a hundred Servers, and works with it on them. This script runs for over a week. As I learned about the Foreach-Object -parallel Feature, I thought this would speed up the script considerably. But I ran into a problem. Since I am not very PowerShell knowledgeable, and I didn't find a post about this problem anywhere, I thought, I going to try my luck and ask here:

Expected and actual results

I want to pass a variable to the executed scriptblock in the foreach-object cmdlet, like here:

$test = "123"
1..3|foreach-object -parallel {param($test);echo "$_, $test"} -ArgumentList($test)

What I expect:

1, 123
2, 123
3, 123

What I get:

ForEach-Object: Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.

What am I doing wrong?

It might be an trivial problem. But since I don't get anywhere and don't find any post/code example. I post it here. I am thankful for answers.

1
If the script runtime is over a week, I think you'd need a major rewrite in the architecture. Parallel processing might be one approach, but there likely are other and smarter ways. - vonPryz
i suspect you need a total rework of the process. one way would be to drop the copy command to the remote systems & let them do the copy. your current outline gives the impression that you are copying from a source, to the system that is running the code, and - finally - to the destination. a faster method would be from the source to the destination - and have it controlled on the destination side. - Lee_Dailey
@Lee_Dailey Exactly this is what I am trying to do. I got the script like you mentioned like this: foreach Server copy cab-file, do stuff. I am doing it now like this: servers|foreach-object -parallel{invoke command to server (copy cab-file, do stuff)}. To ensure readability, I want to define the variables, functions outside of the foreach-object, and pass them. There I ran into my problem. - Sukram22
ah! i don't see that in your Question ... but it looks like MartinBrandl has pointed out the problem & the fix. excellent! [grin] - Lee_Dailey

1 Answers

4
votes

You can simplify that by using the using keyword :-)

$test = "123"
1..3 | foreach-object -parallel { echo "$_, $($using:test)" }