作为参数传递给模块函数时,Scriptblock 未获得管道变量绑定

Voo*_*Voo 4 powershell module powershell-module powershell-4.0

我想把这个功能

function Test-Any {
    [CmdletBinding()]
    param($EvaluateCondition,
        [Parameter(ValueFromPipeline = $true)] $ObjectToTest)
    begin {
        $any = $false
    }
    process {
        if (-not $any -and (& $EvaluateCondition $ObjectToTest)) {
            $any = $true
        }
    }
    end {
        $any
    }
}
Run Code Online (Sandbox Code Playgroud)

到一个模块中。我刚刚创建了一个新模块 my-scripts.psm1 文件,其中仅包含上述函数并使用Import-Module <absolute path>.

问题是,如果我使用模块中的函数1..4 | Test-Any { $_ -gt 3 }会返回 false,因为$_未设置为来自管道的值。

如果我在脚本中正常定义该函数并从那里使用它,它会按预期工作(为 $_ 分配整数值)。

Windows 7 下的 PowerShell v4.0 会发生这种情况。

use*_*407 5

该命令:& $EvaluateCondition $ObjectToTest\xe2\x80\x94 不会将任何内容绑定到$_. param()如果中没有块ScriptBlock, 的值$ObjectToTest将绑定到$args[0]

\n\n
$SB = {"`$_: \'$_\'; `$args[0]:\'$($args[0])\'"}\n1..3 | ForEach-Object {& $SB ($_+3)}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
$SB = {"`$_: \'$_\'; `$args[0]:\'$($args[0])\'"}\n1..3 | ForEach-Object {& $SB ($_+3)}\n
Run Code Online (Sandbox Code Playgroud)\n\n

为什么引用有效:您只需从父作用域$_引用变量即可。$_

\n\n

您看到的值$_是传递给函数的当前管道输入对象Test-Any

\n\n
function Test-Any {\n    param($EvaluateCondition)\n    process {\n        "Test-Any `$_: \'$_\'"\n        & $EvaluateCondition\n    }\n}\n1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:\'$_\'"}}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
$_: \'1\'; $args[0]:\'4\'\n$_: \'2\'; $args[0]:\'5\'\n$_: \'3\'; $args[0]:\'6\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

当您Test-Any在模块范围中定义时,$_带有管道输入的变量Test-Any也会在该模块范围中定义,并且在模块范围之外不可用。

\n\n
New-Module {\n    function Test-Any {\n        param($EvaluateCondition)\n        process {\n            "Test-Any `$_: \'$_\'"\n            & $EvaluateCondition\n        }\n    }\n} | Out-Null\n1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:\'$_\'"}}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
function Test-Any {\n    param($EvaluateCondition)\n    process {\n        "Test-Any `$_: \'$_\'"\n        & $EvaluateCondition\n    }\n}\n1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:\'$_\'"}}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您想调用绑定到某个值的脚本块$_,那么一种方法是:

\n\n
ForEach-Object $EvaluateCondition -InputObject $ObjectToTest\n
Run Code Online (Sandbox Code Playgroud)\n