如何控制PowerShell脚本块

时间:2017-05-03 09:39:47

标签: powershell closures scriptblock

我有一个用PowerShell编写的函数:

function replace([string] $name,[scriptblock] $action) {
    Write-Host "Replacing $name"
    $_ = $name
    $action.Invoke()
}

并将用作:

$name = "tick"
replace $agentPath\conf\buildAgent.dist.properties {
    (cat templates\buildAgent.dist.properties.tpl) `
        -replace '@@serverurl@@', 'http:/localhost:8080/teamcity' `
        -replace '@@name@@', $name `
        > $_
}

但是我发现在scriptblock中,变量$name$name函数中的replace param覆盖。

是否有办法执行脚本块,以便只将变量$_添加到scriptblock的范围中,但没有其他内容?

2 个答案:

答案 0 :(得分:0)

您可以在 scriptblock 中使用$global: 前缀作为$name变量:

$name = "tick"
replace $agentPath\conf\buildAgent.dist.properties {
    (cat templates\buildAgent.dist.properties.tpl) `
        -replace '@@serverurl@@', 'http:/localhost:8080/teamcity' `
        -replace '@@name@@', $global:name `
        > $_
}

答案 1 :(得分:0)

我在答案之前声称powershell仅适用于虐待狂。诀窍在于,如果将函数放入模块中,则局部变量将变为私有,并且不会传递给脚本块。然后传入$_变量,你必须跳更多的箍。

gv '_'获取powershell变量$_并通过InvokeWithContext将其传递给上下文。

现在我知道的比我想要的更多:|

New-Module {
    function replace([string] $name,[scriptblock] $action) {
        Write-Host "Replacing $name"
        $_ = $name
        $action.InvokeWithContext(@{}, (gv '_'))
    }
}

和以前一样

$name = "tick"
replace $agentPath\conf\buildAgent.dist.properties {
    (cat templates\buildAgent.dist.properties.tpl) `
        -replace '@@serverurl@@', 'http:/localhost:8080/teamcity' `
        -replace '@@name@@', $name `
        > $_
}