Try / catch has no effect

I'm new to powershell and I'm trying to add error handling using try / catch statements, but they don't seem to catch 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 cannot communicate with a specific computer, I get this in the console, and not in my clean 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

+66
powershell
Jul 17 '09 at 9:16
source share
7 answers

I was able to duplicate your result when trying to run a remote WMI request. The thrown exception is not caught by Try / Catch, and the trap will not catch it, as this is not a "final error". PowerShell has termination errors and non-termination errors. It seems that Try / Catch / Finally and Trap only work with trailing errors.

It is written to the $ error automatic variable, and you can test for this type of error endlessly by looking at $? an automatic variable that will tell you if the last operation was successful ($ true) or failed ($ false).

When an error occurs, it appears that the error is returned and does not end in a catchable exception. The following is a trace of the generated error.

 PS C:\scripts\PowerShell> 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 

Work for your code could be:

 try { $colItems = get-wmiobject -class "Win32_PhysicalMemory" -namespace "root\CIMV2" -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 } 
+70
Jul 17 '09 at 16:31
source share

If you want try / catch to work for all errors (and not just for final errors), you can manually complete all errors by setting ErrorActionPreference.

 try { $ErrorActionPreference = "Stop"; #Make all errors terminating get-item filethatdoesntexist; # normally non-terminating write-host "You won't hit me"; } catch{ Write-Host "Caught the exception"; Write-Host $Error[0].Exception; }finally{ $ErrorActionPreference = "Continue"; #Reset the error action pref to default } 

Alternatively ... you can create your own trycatch function that accepts script blocks so that your catch catch calls are not like kludge. I believe true / false just in case I need to check if there was an error ... but this is not necessary. In addition, exception logging is optional and can be taken into account in catch, but I always called the logging function in the catch block, so I added it to the try catch function.

 function log([System.String] $text){write-host $text;} function logException{ log "Logging current exception."; log $Error[0].Exception; } function mytrycatch ([System.Management.Automation.ScriptBlock] $try, [System.Management.Automation.ScriptBlock] $catch, [System.Management.Automation.ScriptBlock] $finally = $({})){ # Make all errors terminating exceptions. $ErrorActionPreference = "Stop"; # Set the trap trap [System.Exception]{ # Log the exception. logException; # Execute the catch statement & $catch; # Execute the finally statement & $finally # There was an exception, return false return $false; } # Execute the scriptblock & $try; # Execute the finally statement & $finally # The following statement was hit.. so there were no errors with the scriptblock return $true; } #execute your own try catch mytrycatch { gi filethatdoesnotexist; #normally non-terminating write-host "You won't hit me." } { Write-Host "Caught the exception"; } 
+60
Feb 12 '11 at 20:30
source share

It is also possible to set the preferred action for individual cmdlets, and not just for the entire script. This is done using the ErrorAction parameter (alisa EA), which is available for all cmdlets.

Example

 try { Write-Host $ErrorActionPreference; #Check setting for ErrorAction - the default is normally Continue get-item filethatdoesntexist; # Normally generates non-terminating exception so not caught write-host "You will hit me as exception from line above is non-terminating"; get-item filethatdoesntexist -ErrorAction Stop; #Now ErrorAction parameter with value Stop causes exception to be caught write-host "you won't reach me as exception is now caught"; } catch { Write-Host "Caught the exception"; Write-Host $Error[0].Exception; } 
+15
Sep 14
source share

This is my decision. If Set-Location fails, it throws an error that does not depend on completion, which is not considered by the catch block. Adding -ErrorAction Stop is the easiest way.

 try { Set-Location "$YourPath" -ErrorAction Stop; } catch { Write-Host "Exception has been caught"; } 
+6
Sep 13 '16 at 10:35
source share

Adding "-EA Stop" solved this for me.

+3
May 13 '15 at 15:42
source share

Edit: As noted in the comments, the following solution applies only to PowerShell V1.

See this Adam Weigert Technical Adventure blog post for details on how to implement this.

Usage example (copying / pasting from Adam Weigert's blog):

 Try { echo " ::Do some work..." echo " ::Try divide by zero: $(0/0)" } -Catch { echo " ::Cannot handle the error (will rethrow): $_" #throw $_ } -Finally { echo " ::Cleanup resources..." } 

Otherwise, you will have to use an exception exception .

+1
Jul 17 '09 at 9:29
source share

In my case, this was because I caught only certain types of exceptions:

 try { get-item -Force -LiteralPath $Path -ErrorAction Stop #if file exists if ($Path -like '\\*') {$fileType = 'n'} #Network elseif ($Path -like '?:\*') {$fileType = 'l'} #Local else {$fileType = 'u'} #Unknown File Type } catch [System.UnauthorizedAccessException] {$fileType = 'i'} #Inaccessible catch [System.Management.Automation.ItemNotFoundException]{$fileType = 'x'} #Doesn't Exist 

Added them to handle additional exceptions that cause a final error, as well as unexpected exceptions

 catch [System.Management.Automation.DriveNotFoundException]{$fileType = 'x'} #Doesn't Exist catch {$fileType='u'} #Unknown 
0
Jun 27 '19 at 20:44 on
source share



All Articles