Stop a Powershell Script on Error

PowerShell errors come in two flavors – terminating and non-terminating errors.

Terminating errors stop the execution of the code if they are not handled, whereas non-terminating errors do not terminate the current code execution. Instead, the error is raised, and the execution of the rest of the script is continued.

Examples of Terminating and Non-Terminating Errors

Examples of non-terminating errors:

The above examples show that the errors from Get-ChildItem and Get-ChildItme did not stop the execution of the next command (Write-Host). In the first example, the -Path provided does not exist, and in the second command, we have a typo on the cmdlet (Get-ChildItme instead of Get-ChildItem).

Example of a terminating error – a syntax error:

"56"++67; Write-Host "Hello World!"

Syntax errors like the one shown above are terminating. The execution was halted when ParserError was raised. That was why the Write-Host command was not executed this time round.

The rest of the article discusses ways to stop the execution of a PowerShell script even when a non-terminating error is encountered.

We will be discussing three methods to do that.

Method 1: Using the “Throw” and “Write-Error” Keywords to Raise Exceptions

This method allows the user to raise an error explicitly whenever a given condition is met.

Consider the following PowerShell script. The script checks if a folder exists or not using an if-statement. This code will not raise any error whether or not the folder exists.

File: .\test_script2.ps1

We can raise a non-terminating error if the folder does not exist using the Write-Error cmdlet, as shown below.

File: .\test_script3.ps1

This time around, a “Folder doesn’t exist!” error is raised, but it’s non-terminating – the code execution is not halted because of this error which is why the Write-Host command in the last line of the script is executed.

To stop the execution of the script if the folder does not exist, you should explicitly raise a terminating error using the “Throw” keyword, as shown below.

File: .\test_script4.ps1

As shown in the example, “Folder doesn’t exist” raises a terminating exception – when the error is encountered, the execution is stopped.

This approach is useful if the rest of the code depends on whether the folder exists. For instance, in the example above Get-ChildItem command depends on the existence of the $folder being checked in the if-statement.

Method 2: Using Error Related Preference Variables – $ErrorActionPreference and $ErrorAction

There are several error preference variables in PowerShell. This method will cover two of them:

  1. $ErrorAction

This variable determines how a cmdlet being executed responds to a non-terminating error. Accepted values include: Continue (default), Break, Suspend, Ignore, Inquire, Stop, and, SilentlyContinue.

If we want to stop a PowerShell script on error, we pass the “Stop” value to the variable. Note that this variable only controls the behavior of the cmdlet for which the variable is passed.

  1. $ErrorActionPreference

This is a global error-related preference variable that determines the behavior of a cmdlet when a non-terminating error is encountered. Like $ErrorAction, the accepted values include Continue (default), SilentlyContinue, Stop, Inquire, Ignore, Suspend, and Break.

If we want to halt PowerShell execution on error, we must pass the “Stop” value to the variable. Unlike the $ErrorAction, $ErrorActionPreference is a global variable; when defined, all non-terminating errors raised after it for the current PowerShell session are affected. It is often defined at the start of the script.

The following code shows how to use the $ErrorAction variable. The comments on the code explain what’s happening in each line.

File: .\test_script5.ps1

Output:

The last Write-Host command was not executed because the -ErrorAction was set to “Stop” for the Get-ChildItem command in the previous code line (setting $ErrorAction to “Stop” effectively converted the non-terminating error into a terminating one).

Using the $ErrorActionPreference global variable is simple. Just add

$ErrorActionPreference “Stop”

at the top of the script, and the script execution will be stopped as soon as a terminating or non-terminating error is encountered.

Note 1: $ErrorAction overrides the effects of $ErrorActionPreference.

Methods 1 and 2 discussed above primarily work with cmdlets but not with errors from executables. Let’s discuss stopping a PowerShell script on error when working with executables.

Method 3: Checking the Execution Status or the Exit Code

Some standard Windows variables capture the execution status and exit code of a given command or executable. We will discuss two in this case.

  • $? – this variable shows the execution status of the last operation. True means the operation was completed successfully with no errors and False means at least one error was encountered.
  • $LASTEXITCODE – this variable returns the exit code for the last operation – 0 means success, and one means failure.
  • Bonus: $Error variable holds the upto 256 errors generated during the current PowerShell session.

Based on the value returned by $? and $LASTEXITCODE, you can use the if-statement and “Throw” keywords to exit the scrip execution if an error is raised (See Method 1).

Note 2: It is a convention that the $LASTEXITCODE=1 when the last operation was completed successfully and 0 otherwise. Some Windows applications do not obey this convention. It is therefore recommended to check the meaning of the returned exit code on the documentation of the executable you are running.

Conclusion

This article covers three ways of stopping a PowerShell script execution when a non-terminating error occurs.

The first method discussed using the Write-Error cmdlet or Throw keyword to raise non-terminating or terminating explicitly whenever a given condition is met.

In Method 2, we discussed using $ErrorActionPreference and $ErrorAction variables to deal with non-terminating errors. Lastly, we covered how to deal with non-terminating errors when executables.