I\'m trying to put this function:
function Test-Any {
[CmdletBinding()]
param($EvaluateCondition,
[Parameter(ValueFromPipeline = $true)] $Obj
That command: & $EvaluateCondition $ObjectToTest — does not bind anything to $_. In absence of a param() block in ScriptBlock, the value of $ObjectToTest will be bound to $args[0].
$SB = {"`$_: '$_'; `$args[0]:'$($args[0])'"}
1..3 | ForEach-Object {& $SB ($_+3)}
Output:
$_: '1'; $args[0]:'4'
$_: '2'; $args[0]:'5'
$_: '3'; $args[0]:'6'
Why does referencing $_ work: you simply reference the $_ variable from the parent scope.
The value of $_ that you see, is a current pipeline input object, passed to the Test-Any function.
function Test-Any {
param($EvaluateCondition)
process {
"Test-Any `$_: '$_'"
& $EvaluateCondition
}
}
1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:'$_'"}}
Output:
Test-Any $_: '3'
EvaluateCondition $_:'3'
Test-Any $_: '4'
EvaluateCondition $_:'4'
Test-Any $_: '3'
EvaluateCondition $_:'3'
Test-Any $_: '4'
EvaluateCondition $_:'4'
When you define Test-Any in module scope, then variable $_ with pipeline input to Test-Any also got defined in that module scope and was not available outside of it.
New-Module {
function Test-Any {
param($EvaluateCondition)
process {
"Test-Any `$_: '$_'"
& $EvaluateCondition
}
}
} | Out-Null
1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:'$_'"}}
Output:
Test-Any $_: '3'
EvaluateCondition $_:'1'
Test-Any $_: '4'
EvaluateCondition $_:'1'
Test-Any $_: '3'
EvaluateCondition $_:'2'
Test-Any $_: '4'
EvaluateCondition $_:'2'
If you want to invoke a script block with some value bound to $_, then one way to do this would be:
ForEach-Object $EvaluateCondition -InputObject $ObjectToTest