Error and Exception Handling using Try/catch in powershell




One of the most important components for creating PowerShell scripts is error and exception handling.

I've personally made mistakes while writing scripts without proper exceptions and trying to figure out why it got terminated.😵 

Error and exception handling is often a forgotten component of scripting because it's common to feel that the code should always execute linearly and in an implicit fashion.





This is due to the common practice of taking the small scripts and using them as starting points for more complex scripts. 

The more complex you build your scripts, the higher the probability of failure 🠝 and unexpected results.



In this post, you will learn the following:
  • Types of error
  • Different ways to handle Exceptions
  • Error and exception handling with parameters
    • Different Actions
  • Error and exception handling with Try/Catch


PowerShell has two different types of errors which are terminating and non-terminating.

Terminating errors will stop the script from executing further commands. 

The non-terminating errors will call the write-error cmdlet, print an error to the screen, and continue.


Error and Exception Handling 

PowerShell offers several different options to achieve error and exception handling.

The most popular method used to catch non-terminating errors is bypassing the error and exception handling parameters while executing PowerShell cmdlets. 

You can then call the error variable and execute other actions based on the contents of the $error variable.


The PowerShell parameters that handle error and exceptions are -WarningAction and ErrorAction

When an issue occurs with your script, the PowerShell CLR will reference the -ErrorAction and -WarningAction arguments to determine what the next step for the script is.


There are five actions that are supported within PowerShell. 

  • The SilentlyContinue action will suppress the error and warning information, populate the error variables, and continue.
  • The Ignore action will suppress the warning and error message and not populate any specified variables.
  • The Continue action will write to the screen the warning and error information and attempt to continue with the script.
  • The Stop action will write the warning and error information stop the execution of the script.
  •  The Inquire action will prompt the end-user if they want to HaltSuspendAccept the Error, or Accept All Errors.


By default, PowerShell is set to Continue, however, you can set the $errorActionPreference and $warningActionPreference (Global variables) to different values for different default actions.


We will see one example of cmdlet error handling.


Function TestExample($tesparam) { 
Get-service $tesparam –ErrorAction SilentlyContinue –ErrorVariable err

    If ($err) {
      Write-host "Error! Error Details: $err"
        return
    }
  
    Write-host "Successfully Retrieved Service Information for $svcName. "
}
TestExample "Windows Update"
Write-host "" 
TestExample "Does Not Exist"

####################################################
Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  wuauserv           Windows Update                        
Successfully Retrieved Service Information for . 

Error! Error Details: Cannot find any service with service name 'Does Not Exist'.


If the $err variable has data in it or is implied true, the script will write to the console Error! Error Details: $err followed by return, which will exit out of the function. If the $err variable doesn't have any error details, it will proceed to write to the console.


Handling error with try/Catch/Finally

One of the more popular error and exception handling techniques is leveraging Try/Catch methodology.

The Try/Catch block is used for handling terminating errors and has a very simple structure. You first use the Try { } section of code and then use Catch { } to catch any errors and perform actions based on the errors.



try
{
    $items = Get-Item -Path C:\Does\Not\Exist, C:\Windows, $env:APPDATA -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException]
{
    # Specific catch block for the exception type
    # PSItem contains the error record, and TargetObject may contain the actual object raising the error
    Write-Host ('Could not find folder {0}' -f $PSItem.TargetObject)
}
finally
{
    # Regardless of whether an error occurred or not, the optional
    # finally block is always executed.
    Write-Host 'Always executed'
}

You can find out which type of exception occurred by examining its type, using $Error[0].Exception.GetType().FullName.



One of the best practice techniques for error and exception handling is to combine the use of the Try/Catch block and cmdlet parameters. This is due to PowerShell being able to gracefully handle terminating and non-terminating error scenarios. 


For instance, if you execute a line of code that throws a warning message but doesn't generate a terminating error, you can catch the warning and perform actions based on that warning.



Try {
    Get-process "Doesn't Exist" –ErrorAction SilentlyContinue     –ErrorVariable err
}
Catch {
  Write-host "Try/Catch Exception Details: $_"
}
if ($err) {
  Write-host "Cmdlet Error Handling Error Details: $err"
}

#############################################
Cmdlet Error Handling Error Details: Cannot find a process with the name "Doesn't Exist". Verify the process name and call the cmdlet again. 



When you execute the script, you see that the Catch method doesn't catch the error message from the get-service  the cmdlet. This is due to the error being a non-terminating error, and so it doesn't invoke the block


When you run the script, however, the cmdlet properly handles the error and places the error details in the $err variable. 

Quick Summary: 
  • There are two types of errors in PowerShell: terminating and nonterminating.
  • Error records are written directly to the default output.
  • Error records are rich objects.
  • The $error variable stores the last 256 errors (by default).
  • You can specify a specific variable for errors by using the -ErrorVariable parameter.
  • $? stores a Boolean value indicating the execution status of the last command.
  • $ErrorActionPreference and the -ErrorAction parameter can be used to control the action taken if an error occurs.
  • Terminating errors and exceptions can be managed by the trap statement or the try/catch/finally statements (preferred).
Happy Coding!


Alll the world is a laboratory to the inquiring mind! Join Us

Comments

Popular posts from this blog

Android Navigation Drawer sliding menu with fragments

Design a Beautiful Login Screen for your Android App

Android Actionbar Navigating with Swipeable Tabs