As I've stated before, the three factors to consider when writing production-quality PowerShell functions are input, output and errors. My last article looked at the parameters (input) of functions in Windows PowerShell.
Simply put, you cannot do production-quality functions unless you learn to deal with errors. Failing to consider error conditions will put your users in a bad spot when things go wrong.
Error management can be broken into three parts: detection, error detail and handling. Let's first look at hot to detect error conditions.
PowerShell provides three variables for detecting error conditions:
- $lastexitcode -- This contains the exit code of the native command than ran (i.e. ping.exe). This variable is useful for determining if external commands have executed correctly.
- $? -- For every PowerShell command (functions, scripts, cmdlets), a variable is set to $true or $false. If the command completed successfully, PowerShell sets it to $true; otherwise it is set to $false.
- $ErrorActionPreference (referred to as 'ea':) -- PowerShell uses this to
determine what action should be taken if an error is thrown. Here are the valid values:
- Continue (default) -- display the error but continue processing
- SilentlyContinue -- do not display the error and continue with processing
- Stop -- display the error and stop processing
- Inquire -- display the error and prompt the user for action
Now that we can detect that an error has happened we need to figure out what went wrong.
- $error -- This is by far the object with the largest amount of information, as it contains most data regarding the error. An important thing to note is that $error is actually an object, meaning it has properties, methods and even a type -- just like all the other objects. You can see this by piping $error to get-member.
As you can see, there is a ton of information. Here is a list of the most important data:
- ErrorDetails -- provides the details of the error (often empty)
- Exceptions -- the actual exception that was thrown
- TargetObject -- the object that the operation was being performed on when the error occured
- InvocationInfo --contains detailed information about the command that was run (such as line number, cmdlet and position)
There are two options for handling errors:
- Trap -- This is a keyword that, in a way, acts like a function. It specifies a
list of statements to run when a terminating error occurs.
"Whoops… something broke!"
- Try/Catch -- This works as a wrapper around a block of code that basically says
"Try this, and if that fails, do this."
<something breaks here>
This code doesn't run
"Whoops… something broke!"
Error handling is important art, but to do it effectively, you need to practice. You now have some of the basic tools to do so, but of course there is far more to learn. Here are some additional links to help cover the full gambit of PowerShell error handling, both from my own blog and the Microsoft website.
The rabbit hole awaits!
Miss a column? Check out our Scripting School archive.
ABOUT THE AUTHOR
Brandon Shell has been in the IT industry since 1994. He started out as a PC tech and general fix-it guy for numerous companies. In 2007, he joined the PowerShell MVP ranks, and Shell has spent the past several years building his PowerShell knowledge and helping others build theirs.
This was first published in September 2010