Powershell Job Always Shows Complete

2019-08-30 00:11发布

问题:

I just started working with powershell about 3 days ago and i've been trying to make a script that accesses the registry of a remote computer and looks for a certain key and puts the output into the file.

I have been able to get it to work but i noticed that if it fails to reach the registry it would take about 15 seconds to error out and continue with the script so i put this in:

$Server = "test.contesto.net"

$Job = Start-Job ScriptBlock{[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$Server)

Start-Sleep 2

If ($Job.State -EQ "Completed"){
write-host "made it"
}
Else {
write-host "failed"
}

and i will always get "made it". even when i know i can't reach that servers registry. The odd thing is, if i type all that in manually into a powershell prompt like this:

$Job = Start-Job ScriptBlock {[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine","test.contesto.net") 

Then look at the state of that job

$Job.State

I get "Running" for the full 15 seconds that it takes to fail. i tried to add the Get-Variable in the ScriptBlock {} but that didn't work either. It still shows completed. So i'm thinking that it has to do with the job erroring out due to syntax or something so the job completes every time no matter what

回答1:

The issue is that you need to pass $server as an argument to your script block, then reference it via the automatic variable called $args:

$server = "test.contesto.net"
$Job = Start-Job -ScriptBlock {
    $server = $args[0]
    [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$server) 
} -ArgumentList @($server)

Background jobs run in a completely separate context from your current script, therefore the variables defined locally will not be seen.

So in your case, the job failed immediately because $server was equal to $null. By passing $server appropriately the job will try to retrieve the remote key, then time out.