Why does -Verbose disable the use of $ ErrorActionPreference?

Take this script:

Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' try { echo "ErrorActionPreference = $ErrorActionPreference" Copy-Item "this_is_a_bad_path" Write-Host "Did not catch error" } catch { Write-Host "Caught Error" } 

This works as expected with this output:

 ErrorActionPreference = Stop Caught Error 

But if I add -verbose to the string, giving me Copy-Item -verbose "this_is_a_bad_path" , $ErrorActionPrefrence no longer used, and I get this output:

 ErrorActionPreference = Stop Copy-Item : Cannot find path 'C:\Users\porter.bassett\this_is_a_bad_path' because it does not exist. At C:\Users\porter.bassett\dot.ps1:7 char:3 + Copy-Item -verbose "this_is_a_bad_path" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\Users\porter...s_is_a_bad_path:String) [Copy-Item], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand Did not catch error 

To make it work correctly with -verbose turn, on, I need to add -ErrorAction Stop to the line giving me Copy-Item -verbose "this_is_a_bad_path" -ErrorAction Stop

Why can't I rely on $ErrorActionPreference when using -verbose ?

+7
powershell
source share
3 answers

This is a feature / error in PowerShell, also discussed here in Technet: A detailed general parameter disables ErrorActionPreference .

This feature / bug is present in PowerShell 4 and in the latest version 5.

+1
source share

Well, I have no reason, but this triple-palm problem (well, at least IMHO) is still active in open source PS code:

https://github.com/PowerShell/PowerShell/blob/02b5f357a20e6dee9f8e60e3adb9025be3c94490/src/System.Management.Automation/engine/MshCommandRuntime.cs#L3207 :

  /// <summary> /// ErrorAction tells the command what to do when an error occurs /// </summary> /// <exception cref="System.Management.Automation.ExtendedTypeSystemException"> /// (get-only) An error occurred accessing $ErrorAction. /// </exception> /// <remarks> /// This is a common parameter via class CommonParameters. /// </remarks> internal ActionPreference ErrorAction { get { // Setting CommonParameters.ErrorAction has highest priority if (IsErrorActionSet) return _errorAction; // Debug takes preference over Verbose if (Debug) return ActionPreference.Inquire; if (Verbose) return ActionPreference.Continue; *** WTF!?! *** // fall back to $ErrorAction if (!_isErrorActionPreferenceCached) { bool defaultUsed = false; _errorAction = Context.GetEnumPreference<ActionPreference>(SpecialVariables.ErrorActionPreferenceVarPath, _errorAction, out defaultUsed); _isErrorActionPreferenceCached = true; } return _errorAction; } 
+1
source share

It is best to specify an error for each command in your module.

write-host foo -ErrorAction Stop

Updated: This blog post is helpful. This explains how global var inheritance causes observable behavior.

https://blogs.technet.microsoft.com/heyscriptingguy/2014/04/26/weekend-scripter-access-powershell-preference-variables/

-one
source share

All Articles