1

In Powershell with the function Start-Job you can call functions if you initialize them beforehand.

$export_functions = 
{
    Function Log($message) {Write-Host $message}
    Function MyFunction($message) {Log($message)}
}

$param1="Hello stack overflow!"
Start-Job -ScriptBlock {MyFunction $using:param1} -InitializationScript $export_functions -ArgumentList @($param1) | Wait-Job | Receive-Job

Would it be possible to use a 'global' function inside the script block as well? So something like:

Function Log($message) {Write-Host $message}

$export_functions = 
{
    Function Log($message) {$Function:Log($message)}
    Function MyFunction($message) {Log($message)}
}

$param1="Hello stack overflow!"
Start-Job -ScriptBlock {MyFunction $using:param1} -InitializationScript $export_functions -ArgumentList @($param1) | Wait-Job | Receive-Job

Or is that not intended after all?

Marab
  • 27
  • 3
  • So you want `Write-Host` to write to your calling session from the job? – Mathias R. Jessen Feb 17 '23 at 14:39
  • That was just an example actually. I want to call a function from a different powershell file, which adds logging lines to a specified file. This function is included in multiple powershell scripts. – Marab Feb 17 '23 at 14:51

1 Answers1

0

One way to capture the function definition from the caller's scope (defined outside the initialization script block) is to use an expandable (double-quoted) string ("..."), i.e. string interpolation, and then use [scriptblock]::Create() to create a script block from the result.

You can combine this technique with defining the code you want to place directly inside the script block as usual:

Function Log($message) { Write-Host $message }

# Use string interpolation to capture the body of function Log ($function:Log)
$export_functions = [scriptblock]::Create(
  "Function Log { $function:Log }`n" +
  {
    Function MyFunction($message) { Log $message }
  }
)

Start-Job -InitializationScript $export_functions { Log 'hi1'; MyFunction 'hi2' } | 
  Receive-Job -Wait -AutoRemoveJob

Note the use of $function:Log to refer to the Log function's body, which is an example of namespace variable notation.

mklement0
  • 382,024
  • 64
  • 607
  • 775