Handle errors in ScriptBlock in Invoke-Command Cmdlet

这一生的挚爱 提交于 2019-11-28 00:58:32

No, you can't get the Errorvariable from the Invoke-Command call to be set the same as in the scriptblock.

But if your goal is "detect and handle errors in the scriptblock, and also get errors returned back to the context of the Invoke-Command caller" then just do it manually:

$results = Invoke-Command -ComputerName server.contoso.com -ScriptBlock {
   try
   {
       New-Service -ErrorAction 1
   }
   catch
   {
       <log to file, do cleanup, etc>
       return $_
   }
   <do stuff that should only execute when there are no failures>
}

$results now contains the error information.

The Invoke-Command argument list is a one way deal. You can either output the error variable in the script e.g. on the last line of the scriptblock put:

$errortext

or better yet, just don't capture the error via the -ErrorVariable at all. The scriptblock output, including errors, will flow back to the caller even over a remote connection.

C:\> Invoke-Command -cn localhost { Get-Process xyzzy } -ErrorVariable errmsg 2>$null
C:\> $errmsg
Cannot find a process with the name "xyzzy". Verify the process name and call the cmdlet again.
    + CategoryInfo          : ObjectNotFound: (xyzzy:String) [Get-Process], ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
    + PSComputerName        : localhost

In general, I think it is much better to keep errors on the error stream, separated from the normal output.

In the strictest sense, I believe the answer is no, you cannot set Invoke-Command's ErrorVariable to the contents of the ErrorVariable inside the script block. The ErrorVariable is only for the command it's attached to.

However, you can pass the variable in the script block out to Invoke-Command's scope. In your code you run your New-Service command with -ErrorVariable errortext. Instead, create your variable in the 'script' scope by prefacing the variable name with "script:", like this: -ErrorVariable script:errortext. That makes the variable available outside of the script block as well as inside.

Now your final line Write-Host("Error out: " + $errortext) will output the error that was generated inside of the script block.

More information here and here.

This is almost certainly not the "correct" answer, but this is what I use when I want Invoke-Command to throw an error in the script.

$error.Clear()
Invoke-Command -ComputerName localhost -ScriptBlock {Command-ThatFails}
$if ($error.Count -gt 0) { throw $error[0] }

If you wanted to keep the error in a variable, you could do the following:

$error.Clear()
Invoke-Command -ComputerName localhost -ScriptBlock {Command-ThatFails}
$if ($error.Count -gt 0) { $myErrorVariable = $error[0] }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!