3

我试图把这个功能

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

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

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

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

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

4

1 回答 1

4

该命令:& $EvaluateCondition $ObjectToTest- 没有将任何内容绑定到$_. 在没有param()块的情况下ScriptBlock, 的值$ObjectToTest将被绑定到$args[0]

$SB = {"`$_: '$_'; `$args[0]:'$($args[0])'"}
1..3 | ForEach-Object {& $SB ($_+3)}

输出:

$_: '1'; $args[0]:'4'
$_: '2'; $args[0]:'5'
$_: '3'; $args[0]:'6'

为什么引用$_有效:您只需$_从父范围引用变量。

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

function Test-Any {
    param($EvaluateCondition)
    process {
        "Test-Any `$_: '$_'"
        & $EvaluateCondition
    }
}
1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:'$_'"}}

输出:

Test-Any $_: '3'
EvaluateCondition $_:'3'
Test-Any $_: '4'
EvaluateCondition $_:'4'
Test-Any $_: '3'
EvaluateCondition $_:'3'
Test-Any $_: '4'
EvaluateCondition $_:'4'

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

New-Module {
    function Test-Any {
        param($EvaluateCondition)
        process {
            "Test-Any `$_: '$_'"
            & $EvaluateCondition
        }
    }
} | Out-Null
1..2 | %{3..4 | Test-Any {"EvaluateCondition `$_:'$_'"}}

输出:

Test-Any $_: '3'
EvaluateCondition $_:'1'
Test-Any $_: '4'
EvaluateCondition $_:'1'
Test-Any $_: '3'
EvaluateCondition $_:'2'
Test-Any $_: '4'
EvaluateCondition $_:'2'

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

ForEach-Object $EvaluateCondition -InputObject $ObjectToTest
于 2015-10-20T15:14:27.743 回答