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 "root\CIMV2" -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
Programvare\Powershell\Get memory of
all computers in AD.ps1:25 char:34
+ $colItems = get-wmiobject <<<< -class "Win32_PhysicalMemory"
-namespace "root\CIMV2" -computername $strComputerName -Credential
$credentials
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject],
COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
This is my solution. When Set-Location fails it throws a non-terminating error which is not seen by the catch block. Adding -ErrorAction Stop is the easiest way around this.
Adding "-EA Stop" solved this for me.
Edit: As stated in the comments, the following solution applies to PowerShell V1 only.
See this blog post on "Technical Adventures of Adam Weigert" for details on how to implement this.
Example usage (copy/paste from Adam Weigert's blog):
Otherwise you'll have to use exception trapping.
It is also possible to set the error action preference on individual cmdlets, not just for the whole script. This is done using the parameter ErrorAction (alisa EA) which is available on all cmdlets.
Example
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.
A work around for your code could be:
If you want try/catch to work for all errors (not just the terminating errors) you can manually make all errors terminating by setting the ErrorActionPreference.
Alternatively... you can make your own trycatch function that accepts scriptblocks so that your try catch calls are not as kludge. I have mine return true/false just in case i need to check if there was an error... but it doesnt have to. Also, exception logging is optional, and can be taken care of in the catch, but i found myself always calling the logging function in the catch block, so i added it to the try catch function.