ForEach-Object Scriptblock parameters

This topic contains 2 replies, has 3 voices, and was last updated by  Don Jones 4 years, 6 months ago.

  • Author
    Posts
  • #4114

    TechieSponge
    Participant

    Get-Help ForEach-Object -full does not explain how the following example works.

    PS C:\> 1..4 | ForEach-Object {'Begin'} {"Process $_"} {'End'}
    Begin
    Process 1
    Process 2
    Process 3
    Process 4
    End
    PS C:\>

    The -Begin and -End are named parameters, with a type of .

    While -Process is listed as position 1.

    To make things even more interesting, there is a new parameter for PS ver 3.0

    -RemainingScripts

    Based on my interpretation of the help output, I would have expected the first scriptblock to be assigned to -Process, and the other two scriptblocks to flag some sort of syntax error. Is this a case where the actual behavior of the cmdlet is just not described well by the documentation conventions used?

    Should I be concerned with cmdlet behavior with respect to parameter processing that does not seem to match the documentation?

    Any insight would be appreciated.

  • #4176

    Poshoholic
    Participant

    Believe it or not, there is an explanation for this behaviour.

    First, you should read this blog post:

    http://becomelotr.wordpress.com/2011/05/22/magic-of-foreach-object/

    Bartek explains what is actually happening here, and also shows you how Trace-Command can be used to see how parameters are bound.  This highlights how ForEach-Object internally evaluates whatever unbound script blocks you pass it and decides what to do with them based on whether or not you have explicitly provided -Begin or -End script blocks.

    Regarding whether or not you should be concerned with cmdlet behaviour with respect to parameter binding not matching the documentation, I don't think you should be too concerned because this is a bit of an anomaly.  I would strongly recommend though that for actual scripts (as opposed to ad-hoc use of PowerShell) that you explicitly use named parameters because it removes any potential for confusion wrt parameter binding.

  • #4197

    Don Jones
    Keymaster

    Amen on the named parameters. That said, it'd be nice if this was doc'd a bit better – and you should consider bugging it on Connect, so that MS can put some attention to it.

You must be logged in to reply to this topic.