如何引用在父作用域中定义的 PowerShell 函数?

时间:2021-04-11 19:30:20

标签: function powershell scope

我正在编写一个 PowerShell 脚本来运行几个后台作业。其中一些后台作业将使用相同的一组常量或实用函数,如下所示:

$FirstConstant = "Not changing"
$SecondConstant = "Also not changing"
function Do-TheThing($thing)
{
    # Stuff
}

$FirstJob = Start-Job -ScriptBlock {
    Do-TheThing $using:FirstConstant
}

$SecondJob = Start-Job -ScriptBlock {
    Do-TheThing $using:FirstConstant
    Do-TheThing $using:SecondConstant
}

如果我想在子作用域中共享变量(或在本例中为常量),我会在变量引用前加上 $using:。但是,我不能用函数来做到这一点;按原样运行此代码会返回错误:

The term 'Do-TheThing' is not recognized as the name of a cmdlet, function, script file, or operable program.

我的问题是:我的后台作业如何使用我在更高范围内定义的小型实用函数?

1 个答案:

答案 0 :(得分:4)

如果更高作用域中的函数在相同会话中的相同(非)模块作用域中,您的代码隐式看到它,因为 PowerShell 的动态作用域.

但是,后台作业在一个单独的进程(子进程)中运行,因此来自调用者范围的任何内容都必须显式传递给这个单独的会话。

这对于变量值来说是微不足道的,带有http.IncomingMessage,但对于函数来说不太明显,但它可以通过一些重复来工作, 通过 $using: scope:

传递函数的 body
# The function to call from the background job.
Function Do-TheThing { param($thing) "thing is: $thing" }

$firstConstant = 'Not changing'

Start-Job {

  # Define function Do-TheThing here in the background job, using
  # the caller's function *body*.
  ${function:Do-TheThing} = ${using:function:Do-TheThing}

  # Now call it, with a variable value from the caller's scope
  Do-TheThing $using:firstConstant

} | Receive-Job -Wait -AutoRemoveJob

上述输出 'thing is: Not changing',如预期。