Error Handling, exceptions and debugging

One of the key parts of any good PowerShell script is error handling.

PowerShell errors are of two types. Terminating and Non-Terminating Errors.

Terminating Error: A terminating error is an error that will halt a function or operation. A serious error during execution that halts the command (or script execution) completely. If you make a syntax error or run out of memory, that is a terminating error. Terminating errors can be caught and handled.
Examples: non-existent cmdlets, syntax errors that would prevent a cmdlet from running, or other fatal errors.

PS C:\> do-something
do-something : The term 'do-something' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ do-something
+ ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (do-something:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Non-Terminating Error: Non-terminating errors allow Powershell to continue and usually come from cmdlets or other managed situations. A non-serious error that allows execution to continue despite the failure. Under normal circumstances they cannot be caught by Try-Catch-Finally.
Examples: operational errors such file not found, permissions problems, etc.

PS C:\> Get-ChildItem C:\temp\ -Recurse
Directory: C:\temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/6/2018 11:49 PM folder1
d----- 1/6/2018 11:49 PM folder2
d----- 1/6/2018 11:50 PM folder3
-a---- 1/6/2018 11:49 PM 0 file1.txt
-a---- 1/6/2018 11:50 PM 0 file2.txt
Get-ChildItem : Access to the path 'C:\temp\folder3' is denied.
At line:1 char:1
  + Get-ChildItem C:\temp\ -Recurse
  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo : PermissionDenied: (C:\temp\folder3:String) [Get-ChildItem], UnauthorizedAccessException
  + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

We can catch the non-terminating erros by specifying -ErrorAction Stop on the end of a cmdlet. The available options with -ErrorAction are SilentlyContinue, Stop, Continue, Inquire, Ignore, Suspend.

Error Action Preference:

$ErrorActionPreference is a global variable saying how PowerShell will treat non-terminating errors.

The default value of $ErrorActionPreference is "Continue". It is not recommended to use $ErrorActionPreference = "SilentlyContinue" as this will suppress all the errors.

SilentlyContinue – error messages are suppressed and execution continues.
Stop – forces execution to stop, behaving like a terminating error.
Continue – the default option. Errors will display and execution will continue.
Inquire – prompt the user for input to see if we should proceed.
Ignore – (new in v3) – the error is ignored and not logged to the error stream. Has very restricted usage scenarios.

Try-catch-finally:

Catching a Terminating Error:
We use PowerShell try – catch to catch to catch terminating error.

Try {
#Do some stuff
}
Catch {
#Got an error do something else
}

try{
  do-something
}
catch{
  $_.Exception.Message
}

The term 'do-something' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

In the above example, only the error is caught. We can store this value to a variable if required. It failed to execute the given command in try block. So exception is caught.