Powershell pass variable to start-job

To complement Keith Hill’s helpful answer with a PSv3+ alternative:

The $using: scope modifier can be used to reference the values of variables in the caller’s scope inside the script block passed to Start-Job, as an alternative to passing arguments (by default, a script block executed as a background job does not see any of the caller’s variables or other definitions):

$Servername="Server1"
Start-Job { "Target: " + $using:ServerName } | Receive-Job -Wait -AutoRemoveJob

The above yields:

Target: Server1

Note:

  • The same technique can be used with:

    • Invoke-Command for remote execution – see this question.

    • Start-ThreadJob, available by default in PowerShell (Core) v6+, installable on demand in Windows PowerShell.

    • ForEach-Object -Parallel, available in PowerShell (Core) v7+ only.

  • Note that, as with -ArgumentList (-Args), it is only variable values that are being passed, not the variables themselves; that is, you cannot modify the caller’s variables.[1]


[1] However, the thread-based concurrency features – Start-ThreadJob and ForEach-Object Parallel – permit indirect modification, namely if the variable value at hand happens to be an instance of a (mutable) .NET reference type, such as a hashtable, in which case the object that that the variable “points to” can be modified (if it is mutable). Note that taking advantage of that requires additional, nontrivial effort to make the concurrent modifications thread-safe, such as by use of concurrent (synchronized) collections – see this answer – and/or explicit locking of individual objects – see this answer.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)