Lunch Lesson: Error Handling in PowerShell
Sometimes, errors are inevitable in a PowerShell script. Here’s how to anticipate them, and handle them gracefully.
To begin with, you need to know that PowerShell has a sort of global error-handling mode, which, by default, is set to “Continue,” which basically means, “display an error message and keep going.” An “error message” isn’t the same thing as an “exception;” error messages show up on the screen but you can’t do anything about them. Exceptions, on the other hand, are yours to command. So to start with, you need to get your commands to throw an exception when something goes wrong, and you do that by adding the -ErrorAction (or -EA) parameter to the command, giving it the value “Stop.”
Get-WmiObject Win32_Service -computerName Server2 -EA Stop
When an exception occurs, PowerShell looks to see if your script has already defined a trap handler:
trap {
# deal with the error here
}
Within the trap handler, you have the special $error object, and $error[0] will contain the error (exception) that resulted in the trap being executed. The special $_ variable will also contain the error that you trapped, which is convenient. Remember: Your trap needs to appear in your script BEFORE the command which throws the exception!
Exceptions still display error messages, which you might want to shut off. To do so within a script, and without affecting the rest of the shell, simply add this to the top:
$ErrorActionPreference = “SilentlyContinue”
That actually sets the default -ErrorAction for all cmdlets, so you won’t see ANY error messages. A cmdlet which overrides that with a local -ErrorAction of “Stop” will produce an error message and throw a trappable exception; the script-level $ErrorActionPreference will act to suppress the error message without preventing your trap from working.
Within your trap, do whatever you want. At the end, specify one of two keywords:
- Break will exit the current scope and pass the original exception up to the calling scope, which must either deal with it in its own trap or go ahead and display it.
- Continue will skip over the line of code which threw the exception and continue execution on the next line - but will stay within the same scope as the trap.
Understanding these two puppies can be a little complex. Let’s set up a scenario:
- You’re in the shell. You haven’t defined any trap handlers in the shell.
- You run a script named ScriptA.ps1. It contains a trap handler, which ends with the “Continue” keyword. On line 5 of the script, you execute a second script, ScriptB.ps1.
- ScriptB.ps1 also defines a trap handler which ends with the Break keyword. On line 10 of ScriptB.ps1, a cmdlet runs with the -EA Stop parameter.
- Line 10 of ScriptB.ps1 has a problem, and so the cmdlet throws an exception.
- The trap handler in ScriptB.ps1 executes, does its thing, and ends with the Break keyword. This exits ScriptB.ps1, passing the original exception to ScriptA.ps1.
- ScriptA.ps1 sees an exception on line 5, because that’s where it executed ScriptB.ps1, and ScriptB.ps1 passed an exception. So the trap handler in ScriptA.ps1 executes.
- That trap handler ends in the keyword Continue - so ScriptA.ps1 resumes executing on line 6. It doesn’t re-enter ScriptB.ps1 and resume execution on line 11 (the line after the one where the original exception happened). We’ve exited ScriptB.ps1 at this point, and there’s no going back.
Read that through a few times if necessary to really “get it.” And then try writing a trap handler of your own for a simple script! I’ll be writing one for my TechNet Magazine column, and I’ll share it in a future post.


