A concept in many programming languages is the exception, and one way to deal with these exceptions is by using a try/catch block in PowerShell.

The try/catch block with an optional finally block creates a "box" around code that forces it to send all thrown exceptions into the catch block for further processing.

PowerShell has two types of errors: terminating errors and non-terminating errors. When you see that nasty red text on the screen, you can immediately see an error has occurred, but you can't immediately figure out if that error was a terminating or non-terminating error. All you see is red text!

Was there code skipped underneath the spot where the error occurred? If so, it was probably a terminating error. If PowerShell displayed an error but kept processing the rest of the script, chances are it was a non-terminating error. Non-terminating errors do not change code execution. They simply send data out to the error stream and keep going. Terminating errors, on the other hand, terminate the script unless enclosed in a try block.

To simplify things, let's just make all errors terminating by setting $ErrorActionPreference to Stop. This tells PowerShell to treat all errors as terminating even if they start out as non-terminating. A terminating error is the only way we can catch an exception with our catch block.

I'll create a function and then force PowerShell to return an error. Notice I have a Write-Host reference after the error that should also return "I am the code after the error."

function Do-Something {
    param()

    $ErrorActionPreference = 'Stop'

    ## Do stuff here

    ## Return an error
    Write-Error -Message 'Oh no! An error!'

    Write-Host 'I am the code after the error'
}

I execute this function to produce the result below:

PowerShell returns an error

PowerShell returns an error

Notice this never returned "I am the code after the error." This is because Write-Error "threw" an exception or a hard-terminating error that stopped execution altogether. Also, notice we did get the typical red text we're used to.

Perhaps instead of just returning an error to the console, we'd like to do something with this error or perform some other kind of action when it returns an error. This is called error handling. We need a way to capture that exception before it gets to the console. To do that, we can wrap the code inside of a try block accompanied by a catch block.

I don't like that red text, so I'd rather just see the error message and format it in green text. I can make that happen by adding Write-Host in the catch block and returning just the message as shown below.

function Do-Something {
    param()

    $ErrorActionPreference = 'Stop'

    try {
        ## Do stuff here

        ## Return an error
        Write-Error -Message 'Oh no! An error!'

        Write-Host 'I am the code after the error'
    } catch {
        Write-Host $_.Exception.Message -ForegroundColor Green
    }
}
Error message without red text

Error message without red text

This Write-Host example is obviously not too realistic, but inside of the catch block you can do anything. You can revert any changes previously made, return the status of a server, or do nothing at all and leave the catch block blank (not recommended).

Our example function will never execute Write-Host 'I am the code after the error' because Write-Error is throwing the exception into the catch block. But what if I really need this to run regardless of whether it throws an exception or not? In that case, I can add a finally block below the catch block.

function Do-Something {
    param()

    $ErrorActionPreference = 'Stop'

    try {
        ## Do stuff here

        ## Return an error
        Write-Error -Message 'Oh no! An error!'

    } catch {
        Write-Host $_.Exception.Message -ForegroundColor Green
    } finally {
        Write-Host 'I am the code after the error'
    }
}
Try catch with finally block

Try catch with finally block

Notice now it returned the text and will return it whether or not it throws an exception into the catch block. It always executes code inside the finally block regardless of whether it catches an exception or not. The finally block is good for inserting cleanup code like closing down database connections, removing any temporary files created, and so on. PowerShell always executes code inside the finally block.

Subscribe to 4sysops newsletter!

If your code is complex and lots of different commands can throw exceptions, it's always a good idea to enclose the code inside a try block and catch exceptions as they come up. Good error handling shows that the author has not only ensured that the code worked as designed but has also thought ahead and anticipated any problems that may arise as well.

avatar
3 Comments
  1. wand3rvogel 6 years ago

    We can also write code without ‘finally’, simply after ‘catch’…

    • @wand3rvogel,

      There is an interesting information in the official documentation (Microsoft Docs).

      Windows PowerShell runs the Finally block before the script terminates or before the current block goes out of scope.
      A Finally block runs even if you use CTRL+C to stop the script. A Finally block also runs if an Exit keyword stops the script from within a Catch block.

  2. Gyz 6 years ago

    What is your opinion on following article from Powershell Station?
    https://powehttps://powershellstation.com/2017/10/03/missing-point-powershell-error-handling/rshellstation.com/2017/10/03/missing-point-powershell-error-handling/

    According to Mike, he suggests it is better to use something like -ErrorAction Silentlycontinue and -ErrorVariable Err in a Try/Catch block..

    You’re using the ‘$ErrorActionPreference = Stop’ automatic variable in your example…why not use the ‘$ErrorAction = Stop’ parameter under section ‘#Do Stuff here’ ?

    Thanks for sharing
    Gyz

Leave a reply to Luc Fullenwarth (Rank 4) Click here to cancel the reply

Please enclose code in pre tags

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account