PowerShell ErrorAction: Stop, Continue & SilentlyContinue

Master PowerShell ErrorAction. Learn when to use Stop, Continue, or SilentlyContinue. Optimize your scripts with robust error handling strategies.

I once wrote a database backup script that looked perfectly fine on the surface. It ran, displayed a few warning messages, and finished with a "Success" banner. The next morning, I discovered that the critical backup file was empty because a single Get-Content command had failed due to a locked file, but the script kept running. This is a classic symptom of unhandled non-terminating errors. In PowerShell, the default behavior for many cmdlets is to report the error and continue execution, which can lead to silent data corruption. Understanding how to control this flow is where erroraction in powershell becomes your most important tool.

This guide moves beyond simple syntax definitions. It focuses on decision-making: when to halt execution, when to push through, and when to let failures happen quietly. We will explore how to leverage the -ErrorAction common parameter and the $ErrorActionPreference variable to write scripts that are both robust and predictable.

Close-up of colorful programming code displayed on a computer screen.

Understanding Non-Terminating Errors & the ErrorAction Parameter

What is a Non-Terminating Error?

To master error handling, you first need to understand what PowerShell considers a "non-terminating" failure. In most programming languages, an exception stops everything. In PowerShell, however, a non-terminating error is a problem that happens during the processing of a specific item, but the pipeline can technically keep going.

Think of it like a factory assembly line. If one part is defective, a good line operator flags the defect but keeps processing the next part; they don’t shut down the entire plant. PowerShell works similarly. When a cmdlet like Get-Content encounters a file it cannot read, it logs the error, prints it to the console (usually in red), and then moves on to the next file in the pipeline.

This default behavior is designed for flexibility, not for safety. Common cmdlets that generate these errors include:

  • Get-Content when a path is invalid or access is denied.
  • Invoke-WebRequest when a URL returns a 404 or 500 status code.
  • Stop-Process when a process name is not found.

If you are piping multiple objects into these commands, the execution will continue unless you explicitly tell PowerShell to stop.

The -ErrorAction Common Parameter Syntax

The way to override this default "keep going" behavior is the -ErrorAction parameter. This is a "Common Parameter" in PowerShell, meaning nearly every built-in cmdlet and advanced function accepts it. You don't need to define it in your own functions if you use [CmdletBinding()]; it’s built into the language.

The syntax is straightforward. You append the parameter to your command:

Get-Service "NonExistent" -ErrorAction Stop

Here, we are telling PowerShell that for this specific command, if an error occurs, do not just print it and move on; treat it as a critical failure. It is important to remember that this change is local. It only affects the command it is attached to. The next line in your script will revert to whatever the global default is, unless you change that default as well.

Close-up of HTML and PHP code on screen showing error message and login form data.

Decision Guide: Stop vs. Continue vs. SilentlyContinue

Choosing the right powershell erroraction stop vs continue strategy depends entirely on your tolerance for risk. Are you running a critical migration where a single failure should abort the whole process? Or are you cleaning up temporary files where a locked file is expected?

-ErrorAction Stop: Halt Execution on Error

When you use -ErrorAction Stop, you are converting a non-terminating error into a script-terminating error. This is the closest analog to a "try/catch" exception in other languages.

Use this when subsequent steps are dependent on the success of the current command. For example, if you cannot read the configuration file, you cannot start the service. Stopping immediately prevents you from trying to start a service with missing parameters.

In my experience, Stop is the safest default for transactional scripts. However, Stop does not inherently catch errors; it just throws them. To handle the failure gracefully, you must wrap the command in a try/catch block:

try {
    $config = Get-Content "C:\App\config.json" -ErrorAction Stop
    # Proceed with initialization
}
catch {
    Write-Warning "Configuration file missing or unreadable. Aborting."
    exit 1
}

Without the try/catch, the script simply crashes and prints the error to the host. With it, you can log the issue, send an alert, or attempt a fallback.

-ErrorAction Continue & SilentlyContinue: Keep Going

On the other side of the spectrum, you have the default behavior. Continue displays the error message but keeps the script running. SilentlyContinue suppresses the error message entirely, allowing the script to run without noise.

The distinction is subtle but vital. SilentlyContinue does not ignore the error; it just hides the visual feedback. The error record is still added to the automatic variable $Error.

This is ideal for bulk operations. Imagine you have a script to remove 1,000 temporary files. One file is currently open by a user. You don’t want the script to crash. You don’t necessarily want to spam the console with 1,000 "file not found" or "access denied" messages if the process is running quietly.

Here is how you might use it:

Remove-Item "C:\Temp\*.log" -ErrorAction SilentlyContinue

if ($Error.Count -gt 0) {
    Write-Host "$($Error.Count) items failed to remove."
}

A comparison of the visible output vs. the internal state helps clarify the risk:

ValueConsole OutputAdded to $Error?Script Continues?
ContinueYes (Red text)YesYes
SilentlyContinueNoYesYes
StopYes (Critical)YesNo (Throw)
Warning: Relying on SilentlyContinue without checking $Error is a common pitfall. It creates a false sense of security. The error happened; you just chose not to see it.

Global Control: The ErrorActionPreference Variable

Setting -ErrorAction on every single cmdlet is tedious. If you have a script with 50 commands, adding -ErrorAction Stop to each one is cumbersome and prone to human error. This is where the $ErrorActionPreference variable comes in. This erroractionpreference variable sets the default behavior for all commands in the current scope.

Setting Default Behavior for Sessions and Scripts

You can change this variable at different scopes:

  • Per-Script: Add $ErrorActionPreference = 'Stop' at the very top of your script. This makes the script "strict." Any non-terminating error will now break execution.
  • User/Machine Scope: Using Set-Item on the registry or Set-ExecutionPolicy related keys (less common for error preferences, usually done via profile scripts).

The critical rule to remember is precedence: An explicit -ErrorAction parameter always overrides the variable.

For example, if your global preference is Stop, but you have a command that is expected to fail occasionally, you can override it locally:

$ErrorActionPreference = 'Stop'

Get-ChildItem C:\CriticalFolder

Test-Path C:\OptionalCacheFolder -ErrorAction SilentlyContinue

Why Mix? Using Both Parameter and Preference

The best practice I recommend to my teams is a "safe by default, explicit exception" pattern.

  1. Set $ErrorActionPreference = 'Stop' at the start of your script. This ensures that any unexpected failure halts the process immediately, preventing partial states.
  2. Use -ErrorAction SilentlyContinue only for commands where failure is a valid, expected state (e.g., checking if a path exists, attempting to stop a process that might already be stopped).

This hybrid approach creates a robust structure. You aren't guessing which commands are safe; you are explicitly declaring exceptions. If you forget to add the exception to a command that can fail, the script will stop, alerting you to fix the script.

Advanced: ErrorAction vs. Try-Catch-Finally Blocks

Many developers confuse parameter-based error handling with structural error handling. While they work together, they solve different problems.

When -ErrorAction Stop is Insufficient

The phrase "difference between erroraction and try catch" is a common search because they are often used together, but they function differently. -ErrorAction Stop changes the type of error from non-terminating to terminating. It does not handle the error; it just escalates it.

If you use -ErrorAction Stop without a try/catch block, the script dies. It prints the error and stops. The try/catch block is the mechanism that allows you to recover from that death.

Consider this comparison:

Without Try/Catch:


Get-Content "missing.txt" -ErrorAction Stop
Write-Host "This line never runs"

With Try/Catch:

try {
    Get-Content "missing.txt" -ErrorAction Stop
}
catch {
    Write-Host "Caught the error: $($_.Exception.Message)"
}
Write-Host "This line DOES run because we caught the exception"

Handling Terminating Exceptions Directly

It is also worth noting that -ErrorAction does not apply to all errors. Statement-terminating errors, such as syntax errors, division by zero, or calling a method on a null object (.NET exceptions), behave differently.

For instance, [int]::Parse("abc") throws a .NET exception. This is not a standard cmdlet non-terminating error. You cannot suppress a .NET exception with -ErrorAction SilentlyContinue in the same way you can with Get-Content. You must use try/catch to handle these specific exception types.

Use Throw when you want to actively generate an error from your own code. Use Write-Error when you are inside a pipeline processing multiple items and want to signal a failure for one item without stopping the whole pipeline (unless the preference is Stop).

Common Pitfalls & Best Practices for Suppressed Errors

Even experienced PowerShell users fall into traps when using powershell suppress errors with erroraction.

The 'Silent Failure' Trap

The biggest risk with SilentlyContinue is the "Silent Failure." Developers often assume that if they don't see a red error message, the command succeeded. This is dangerously wrong.

In one of my recent audits, I found a deployment script that used SilentlyContinue to install a component. The installation was failing because a prerequisite service was stopped, but the script continued, assuming the install worked. The application then crashed in production.

The fix was simple: always inspect the $Error array or the $? variable after a suppressed command.

$result = Get-ChildItem C:\Protected -ErrorAction SilentlyContinue
if ($Error.Count -gt 0) {
    # Log the specific error details
    $Error[0] | Format-List *
}

Native Executables & Exit Codes

A crucial distinction that is often overlooked: -ErrorAction does not apply to native external programs (like exe files) in standard PowerShell 5.1. If you run ping -n 4 192.168.1.1 -ErrorAction Stop, and the ping fails, PowerShell will not throw a terminating error. The native program just returns an exit code.

To handle native commands, you must check $LASTEXITCODE.

$null = & "C:\Tools\backup.exe" /full
if ($LASTEXITCODE -ne 0) {
    Write-Error "Backup failed with exit code $LASTEXITCODE"
}

Note: In PowerShell 7.4 and later, you can enable $PSNativeCommandUseErrorActionPreference = $true. This makes native commands respect your $ErrorActionPreference settings, allowing you to use Stop with external executables. If you are on an older version, you must stick to exit code checks.

FAQ

What is the default value of ErrorAction in PowerShell? The default is Continue. This means that by default, scripts will display non-terminating errors to the console but will continue executing subsequent commands unless you explicitly change the behavior via the -ErrorAction parameter or the $ErrorActionPreference variable.

Does -ErrorAction Stop terminate the entire host or just the cmdlet? It terminates the execution of the current script or function block. If the error is not caught by a try/catch block, the script stops. It does not close your PowerShell console window or the host application (like ISE or VS Code). The host remains active; the script simply halts.

How to hide error messages in PowerShell scripts? You can use -ErrorAction SilentlyContinue on specific commands to hide the red error text. Alternatively, you can redirect error output to null using 2>$null. However, be careful: 2>$null hides the message but does not stop the error from being recorded in internal variables. SilentlyContinue is generally preferred for logic-based suppression.

Can I use -ErrorAction with native executables? In Windows PowerShell 5.1, no. The parameter is ignored for external programs. You must check $LASTEXITCODE. In PowerShell 7.4+, you can enable this behavior by setting $PSNativeCommandUseErrorActionPreference = $true.

Conclusion

Mastering error handling in PowerShell is about shifting your mindset from "reporting errors" to "controlling flow." Use Stop for critical paths where a single failure invalidates the rest of the work. Use Continue (the default) when you want visibility but need the script to survive individual hiccups. Use SilentlyContinue only when you are certain the failure is expected and you have a mechanism to verify it later via $Error.

Never use these parameters in isolation. Pair them with try/catch blocks for structured recovery, and establish a global $ErrorActionPreference at the top of your scripts to enforce consistent, strict behavior. By combining these techniques, you write scripts that don't just run, but fail intelligently.

Want a quick reference guide for your next project? Download our free "PowerShell ErrorAction Cheat Sheet" (PDF) or read our follow-up article on "Advanced PowerShell Logging Patterns" to track those silent failures.

← Back to Home