简体   繁体   中英

How to refer to a PowerShell function defined in a parent scope?

I'm writing a PowerShell script that runs a couple of background jobs. Some of these background jobs will use the same set of constants or utility functions, like so:

$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
}

If I wanted to share variables (or, in this case, constants) in child scopes, I'd prefix the variable references with $using: . I can't do that with functions, though; running this code as-is returns an error:

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

My question is this: How can my background jobs use a small utility function that I've defined in a higher scope?

If the function in the higher scope is in the same (non-)module scope in the same session , your code implicitly sees it, due to PowerShell's dynamic scoping.

However, background jobs run in a separate process (child process), so anything from the caller's scope must be passed explicitly to this separate session.

This is trivial for variable values, with the $using: scope , but less obvious for functions , but it can be made to work with a bit of duplication, by passing a function's body via namespace variable notation :

# 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

The above outputs 'thing is: Not changing' , as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM