Short question: anyone has detailed information on -RemainingScripts parameter of ForEach-Object?
Long question:
I just started
I did more research and now feel confident to answer the behavior of -RemainingScripts parameter when multiple ScriptBlocks are passed in.
If you run the following commands and inspect the result carefully, you will find the pattern. It's not quite straightforward, but still not hard to figure out.
1..5 | foreach { "process block" } { "remain block" }
1..5 | foreach { "remain block" } -Process { "process block" }
1..5 | foreach { "remain block" } -End { "end block" } -Process { "process block" } -Begin { "begin block" }
1..5 | foreach { "remain block 1" } -End { "end block" } -Process { "process block" } { "remain block 2" }
1..5 | foreach { "remain block 1" } { "remain block 2" } -Process { "process block" } -Begin { "begin block" }
1..5 | foreach { "remain block 1" } { "remain block 2" } -Process { "process block" } { "remain block 3" }
1..5 | foreach { "process block" } { "remain block 1" } { "remain block 2" } -Begin { "begin block" }
1..5 | foreach { "process block" } { "remain block 1" } { "remain block 2" } { "remain block 3" }
So what's the pattern here?
When there's single ScriptBlock passed in: easy, it just goes to -Process (the most common usage)
When exactly 2 ScriptBlocks are passed in, there are 3 possible combinations
If we run these 2 statements:
1..5 | foreach { "process block" } { "remain block" }
1..5 | foreach { "remain block" } -Process { "process block" }
# Both of them will return:
process block
remain block
remain block
remain block
remain block
remain block
As you will find out, this is just a special case of the following test case:
When more than 2 ScriptBlocks are passed in, follow this workflow:
Result of ordering is a collection of ScriptBlocks. Let's call this collection OrderedScriptBlocks
(Internally) Re-bind parameters based on OrderedScriptBlocks
Let's take this example
1..5 | foreach { "remain block 1" } { "remain block 2" } -Process { "process block" } { "remain block 3" }
Order result is:
{ "process block" } # new Begin
{ "remain block 1" } # new Process
{ "remain block 2" } # new Process
{ "remain block 3" } # new End
Now the execution result is completely predictable:
process block
remain block 1
remain block 2
remain block 1
remain block 2
remain block 1
remain block 2
remain block 1
remain block 2
remain block 1
remain block 2
remain block 3
That's the secret behind -RemainingScripts and now we understand more internal behavior of ForEach-Object!
Still I have to admit there's no documentation to support my guess (not my fault!), but these test cases should be enough to explain the behavior I described.