Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Error handling Invoke-Command

Tags:

powershell

For one reason or another I can't seem to get Invoke-Command to produce an error and go the Catch block of my code. I'm probably missing something obvious here, but I can't see it.

I know that the Try block is always executed until a Terminating error is found. By using the switch -ErrorAction Stop, I expect it to become a Terminating error when the server name doesn't exist and move on to the Catch block to report on this error. But it's not really doing that, it just launches the job with Invoke-Commandon the non-existing server. And when not using the switch -AsJob the error is catched. I'm a bit confused on what the best way would be for error handling here..

$Server = "Wrong"

Try {
         if ($Server -eq "UNC") {
             Write-Host "Running Start-Job" -ForegroundColor Cyan
             Start-Job -ScriptBlock { Write-Host "Foo Start-Job" } -Name DelFiles
         }
         else {
              Write-Host "Running Invoke-Command" -ForegroundColor Cyan        
              Invoke-Command -ScriptBlock { Write-Host "Foo Invoke-Command" } -ComputerName "$Server" -AsJob -JobName DelFiles -ErrorAction Stop
         }  
     }
Catch {
    Write-Host "Error detected"
}

Thank you for your help guys, I learned a lot here on StackOverflow. Once I'm getting better at PowerShell I hope to be able to help others out to.

like image 499
DarkLite1 Avatar asked Jun 27 '26 22:06

DarkLite1


1 Answers

as @mjolinor said. The error will be caught in the job, so you will need get-job or receive-job to see if there was an error.

get-job [id] will display the job for you, and you can check the state to see if it failed or completed or is still running, and receive-job [id] will echo back anything that would have normally been printed to stdout

Here is a bit of a test scenario for you I did on my pc This first one I did on a non-existant PC

PS C:\hht> Invoke-Command -ScriptBlock { echo "hey"} -ComputerName test-pc -AsJob
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
22     Job22           RemoteJob       Running       True            test-pc               echo "hey"              

PS C:\hht> Get-Job 22

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
22     Job22           RemoteJob       Failed        False           test-pc               echo "hey"

PS C:\hht> Receive-Job 22

[test-pc] Connecting to remote server test-pc failed with the following error message : WinRM cannot process the request. The following error occurred while using 
Kerberos authentication: Cannot find the computer test-pc. Verify that the computer exists on the network and that the name provided is spelled correctly. For more 
information, see the about_Remote_Troubleshooting Help topic.
+ CategoryInfo          : OpenError: (test-pc:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : NetworkPathNotFound,PSSessionStateBroken

As you can see it failed, so you can catch this in your main script with something like:

if((get-job $id).state -eq "Failed")
{
    echo "There was an error running job on $server"
}

And here is an example that works:

PS C:\hht> Invoke-Command -ScriptBlock { echo "hey"} -ComputerName test2-pc -AsJob
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
24     Job22           RemoteJob       Running       True            test-pc               echo "hey"  

PS C:\hht> Get-Job 24

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
24     Job24           RemoteJob       Completed     False           test2-pc       echo "hey" 

PS C:\hht> Receive-Job 24
hey

As you can see this job completed successfully and running receive-job returns the output from that job that was run on the remote PC

So in your code, the try-catch block will only catch any errors on the local session, not from the script block run on the remote pc

like image 111
mrwhale Avatar answered Jul 01 '26 15:07

mrwhale



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!