Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

powershell - Try/catch does not seem to have an effect

I am new to powershell, and I am trying to add error handling via try/catch statements, but they don't seem to actually be catching the error. This is powershell v2 CP3.

$objComputer = $objResult.Properties;
$strComputerName = $objComputer.name
write-host "Checking machine: " $strComputerName

try
{
    $colItems = get-wmiobject -class "Win32_PhysicalMemory" -namespace "rootCIMV2" -computername $strComputerName -Credential $credentials
    foreach ($objItem in $colItems) 
    {
        write-host "Bank Label: " $objItem.BankLabel
        write-host "Capacity: " ($objItem.Capacity / 1024 / 1024)
        write-host "Caption: " $objItem.Caption
        write-host "Creation Class Name: " $objItem.CreationClassName      
        write-host
    }
}
Catch 
{
    write-host "Failed to get data from machine (Error:"  $_.Exception.Message ")"
    write-host
}
finally 
{ }  

When it fails to contact a specific machine, I get this in console, and not my clean catch message:

Get-WmiObject : The RPC server is
unavailable. (Exception from HRESULT:
0x800706BA) At Z:7.0 Intern
ProgramvarePowershellGet memory of
all computers in AD.ps1:25 char:34
+ $colItems = get-wmiobject <<<< -class "Win32_PhysicalMemory"
-namespace "rootCIMV2" -computername $strComputerName -Credential
$credentials
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject],
COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I was able to duplicate your result when trying to run a remote WMI query. The exception thrown is not caught by the Try/Catch, nor will a Trap catch it, since it is not a "terminating error". In PowerShell, there are terminating errors and non-terminating errors . It appears that Try/Catch/Finally and Trap only works with terminating errors.

It is logged to the $error automatic variable and you can test for these type of non-terminating errors by looking at the $? automatic variable, which will let you know if the last operation succeeded ($true) or failed ($false).

From the appearance of the error generated, it appears that the error is returned and not wrapped in a catchable exception. Below is a trace of the error generated.

PS C:scriptsPowerShell> Trace-Command -Name errorrecord  -Expression {Get-WmiObject win32_bios -ComputerName HostThatIsNotThere}  -PSHost
DEBUG: InternalCommand Information: 0 :  Constructor Enter Ctor
Microsoft.PowerShell.Commands.GetWmiObjectCommand: 25857563
DEBUG: InternalCommand Information: 0 :  Constructor Leave Ctor
Microsoft.PowerShell.Commands.GetWmiObjectCommand: 25857563
DEBUG: ErrorRecord Information: 0 :  Constructor Enter Ctor
System.Management.Automation.ErrorRecord: 19621801 exception =
System.Runtime.InteropServices.COMException (0x800706BA): The RPC
server is unavailable. (Exception from HRESULT: 0x800706BA)
   at
System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at System.Management.ManagementObjectSearcher.Initialize()
   at System.Management.ManagementObjectSearcher.Get()
   at Microsoft.PowerShell.Commands.GetWmiObjectCommand.BeginProcessing()
errorId = GetWMICOMException errorCategory = InvalidOperation
targetObject =
DEBUG: ErrorRecord Information: 0 :  Constructor Leave Ctor
System.Management.Automation.ErrorRecord: 19621801

A work around for your code could be:

try
{
    $colItems = get-wmiobject -class "Win32_PhysicalMemory" -namespace "rootCIMV2" -computername $strComputerName -Credential $credentials
    if ($?)
    {
      foreach ($objItem in $colItems) 
      {
          write-host "Bank Label: " $objItem.BankLabel
          write-host "Capacity: " ($objItem.Capacity / 1024 / 1024)
          write-host "Caption: " $objItem.Caption
          write-host "Creation Class Name: " $objItem.CreationClassName      
          write-host
      }
    }
    else
    {
       throw $error[0].Exception
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...