snakePlantLeaf
snakePlantLeaf

Reputation: 73

Assign a variable inside of a scriptblock while running a job

Related to Terminate part of powershell script and continue.
Partially related to Powershell Job Always Shows Complete.

My script runs locally and access the registry hive of a remote PC. I need the value of registry keys to be written into a $RegHive variable. And I want to monitor it as a job in case some PC freezes, I can terminate the command and move on to another PC.

My original code would be:

$global:RegHive = $null
$job = Start-Job -ScriptBlock {
    $RegHive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("SomeKeyName", "SomePCName")
}

But no matter what I do, the variable $RegHive is empty.

If I do $RegHive = (Get-Job | Receive-Job) some value gets assigned to $RegHive that on one side looks exactly as if I would run it normally without a job/scriptblock, ie:

$RegHive = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("SomeKeyName", "SomePCName")

and even has the same $RegHive.SubKeyCount

But the "normal" one has $RegHive.GetSubKeyName() method and the one from job doesn't.

How do I escape assigning a variable with Receive-Job and do the assignment directly inside the scriptblock, which is run as a job?

In simple words:

$job = Start-Job -ScriptBlock {$a = 1 + 2}

How to get $a be equal to 3 without $a = (Get-job | Receive-job)?

Upvotes: 1

Views: 447

Answers (1)

Robert Cotterman
Robert Cotterman

Reputation: 2268

This might be helpful for you. The job is sort of like a variable What you can do is name the job and then call it by name with -Keep to maintain it's value stored - aka it will store all final output inside itself until you call it. (it can be kept but the default is to remove it once called)

$global:RegHive = $null
Start-Job -Name "RegHive" -ScriptBlock {
    [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("SomeKeyName", "SomePCName")
}
Receive-Job -Name "RegHive" -Keep

obviously calling the Receive-Job immediately after defeats the purpose of jobs, they add a lot of overhead, and are only efficient when needing to do multiple things at once. - if you call for 100s or thousands at once, you could do get-job | wait-job then when finished start using their outputs ---- wait-job also accepts job names or can wait on your entire list of jobs.

another option to set the variable is

$RegHive = "Receive-Job -Name "RegHive"

and finally, you can do this to use the value

get-<insert command> -value "$(Receive-Job -Name 'RegHive' -Keep)" -argument2 "YADA YADA"

remember keep will not delete the value and can be "Received" again later.

Upvotes: 0

Related Questions