Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell - Setting $ErrorActionPreference for the entire script

I've been giving PowerShell (v3.0) a shot for the first time today, and became enormously frustrated with the strange way some of its error-handling concepts are implemented.

I wrote the following piece of code (using the Remote Registry PowerShell Module)

try
{
    New-RegKey -ComputerName $PCName -Key $Key -Name $Value
    Write-Host -fore Green ($Key + ": created")
}
catch
{
    Write-Host -fore Red "Unable to create RegKey: " $Key
    Write-Host -fore Red $_
}

(This is just a snippet)

Apparently the default behavior of PowerShell is to NOT catch errors which are non-terminating. So I added the following line at the top op my script, as recommended by various people:

$ErrorActionPreference = "Stop"

Executing this in the PowerShell ISE did indeed catch all errors. However, execution following command from the terminal still does not catch my errors.

From ISE:

PS C:\windows\system32> C:\Data\Scripts\PowerShell\Error.ps1
Errorhandling:  Stop
SOFTWARE\MySoftware does not exist. Attempting to create
Unable to create RegKey:  SOFTWARE\MySoftware
Key 'SOFTWARE\MySoftware' doesn't exist.

From Command-Line:

PS C:\Data\Scripts\PowerShell> .\Error.ps1
Errorhandling:  Stop
SOFTWARE\MySoftware does not exist. Attempting to create
New-RegKey : Key 'SOFTWARE\MySoftware' doesn't exist.
At C:\Data\Scripts\PowerShell\Error.ps1:17 char:13
+             New-RegKey -ComputerName $PCName -Key $Key -Name $Value
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,New-RegKey

SOFTWARE\MySoftware: created

I have no idea why the behavior of the Preference Variables behaves differently depending on where they are called from, especially since the ISE seems to execute the exact same command?

Based on other feedback, I changed the following line:

New-RegKey -ComputerName $PCName -Key $Key -Name $Value

To:

New-RegKey -ComputerName $PCName -Key $Key -Name $Value -ErrorAction Stop

Using this method, I was able to trap errors from both the command-line and the ISE, but I don't want to specify the error behaviour on each Cmdlet I call, especially because the catching of errors is essential to the proper functioning of the code. (Plus, the fact that this method DOES work only serves to confuse me even more)

What is the proper way of defining error-handling behavior for the scope of an entire script and/or module?

Also, here's my $PSVersionTable:

PS C:\Data\Scripts\PowerShell> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      3.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.18408
BuildVersion                   6.2.9200.16481
PSCompatibleVersions           {1.0, 2.0, 3.0}
PSRemotingProtocolVersion      2.2
like image 438
romatthe Avatar asked Jan 20 '14 22:01

romatthe


People also ask

What is ErrorActionPreference PowerShell?

$ErrorActionPreference. Determines how PowerShell responds to a non-terminating error, an error that doesn't stop the cmdlet processing. For example, at the command line or in a script, cmdlet, or provider, such as the errors generated by the Write-Error cmdlet.

What is the default error action in PowerShell?

By default, the value of $ErrorActionPreference is set to Continue which means that an error will be displayed, but the script (or command) will attempt to continue.

How do I use verbose in PowerShell?

Typically, the verbose message stream is used to deliver more in depth information about command processing. By default, the verbose message stream is not displayed, but you can display it by changing the value of the $VerbosePreference variable or using the Verbose common parameter in any command.

What is SilentlyContinue in PowerShell?

-ErrorAction:SilentlyContinue suppresses the error message and continues executing the command. -ErrorAction:Stop displays the error message and stops executing the command. -ErrorAction:Suspend is only available for workflows which aren't supported in PowerShell 6 and beyond.


1 Answers

Since you're running V3, you also have the option of using $PSDefaultParameterValues:

$PSDefaultParameterValues += @{'New-RegKey:ErrorAction' = 'Stop'}

Normally that will change it in the global scope. If you want to isolate it to just the local or script scope, you can initialize a new one in the local scope first:

$PSDefaultParameterValues = @{}
$PSDefaultParameterValues += @{'New-RegKey:ErrorAction' = 'Stop'}

If you want to inherit what's already in the parent scope and then add to it for the local scope:

 $PSDefaultParameterValues = $PSDefaultParameterValues.clone()
 $PSDefaultParameterValues += @{'New-RegKey:ErrorAction' = 'Stop'}

To set the default ErrorAction for all cmdlets, not just New-RegKey, specify '*:ErrorAction' instead of 'New-RegKey:ErrorAction' in the code above.

like image 138
mjolinor Avatar answered Oct 21 '22 08:10

mjolinor