If you think you understand PowerShell parameter binding, then have a look at this simple function which exposes a little-known PowerShell behavior:
Function Test-Function { param ( [Parameter(ValueFromPipeline=$true)] [Int] $Number, [Parameter(ValueFromPipelineByPropertyName=$true)] [Int] $Number2 ) Process { "Doing something with $Number and $Number2" } }
The function Test-Function accepts two parameters. Both can come from the pipeline. The first is accepting the entire pipeline input ("ByValue"), the second expects pipeline objects with a property "Number2" ("ByPropertyName"). So what do you think would happen when you call it like this:
Right: The numbers sent via pipeline go to parameter -Number, and the parameter -Number2 is always 6. That's what you'd probably have guessed.
However, when you submit a script block to -Number2, everything changes: PowerShell realizes that a script block is not an Integer. The call would have to fail with a type mismatch, but it doesn't. Instead, PowerShell happily accepts the script block and evaluates it, then takes its result as parameter value:
This is unexpected, yet very useful because it allows you to create parameters that dynamically process the data piped into the command. A lot of cmdlets use the very same technique.