Monthly Archive

Categories

Passing data into Jobs

PowerShell jobs are a powerful tool for running processes in the background. You have to remember that a PowerShell job runs in a separate process that only exists for the duration of the job. The results are returned to your process when the job finishes.

 

A user on the forum asked about passing variables into jobs.  He’d done this:

$w = '1..10'
Invoke-Expression $w

and got the expected result

1
2
3
4
5
6
7
8
9
10

 

He then tried this

Start-Job -ScriptBlock { Invoke-Expression $w}

But the job said

Cannot bind argument to parameter 'Command' because it is null.
    + CategoryInfo          : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpre
   ssionCommand
    + PSComputerName        : localhost

 

Irrespective of whether using Invoke-Expression is a good idea  and I’ll cover that in a future post the job fails because its failing to find $w because the job is running in a separate PowerShell process and $w doesn’t exist.

 

The simplest answer is to make the job self contained

Start-Job -ScriptBlock { $w = '1..10'; Invoke-Expression $w}

 

Everything is in the script block passed to the job and therefore passed to the new PowerShell process.

 

Alternatively, you can pass the variable $w into the script block

Start-Job -ScriptBlock { param($w) Invoke-Expression $w} -ArgumentList $w

 

You need to define a param block on the script block and pass the $w variable to it using the –Argumentlist parameter on start-job.

 

Another option introduced with PowerShell 3.0 us the $using scope modifier

Start-Job -ScriptBlock { Invoke-Expression $using:w}

 

Which is another way to say use the $w variable from the current scope

 

You can find out more on $using from about_scopes, about_Remote_Variables

Comments are closed.