You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
-ErrorAction Ignore doesn't work for calling advanced functions #1759
Dot-source that script to import the function definitions.
Call the "bar" function.
Expected result:
Nothing (no output; no error--bar is calling foo with "-ErrorAction Ignore").
Actual result:
I get an error, and it's not even the one written by foo:
Write-Error : The value Ignore is not supported for an ActionPreference variable. The provided value should be used only as a value for a preference
parameter, and has been replaced by the default value. For more information, see the Help topic, "about_Preference_Variables."
At E:\temp\ps_ea_ignore_2.ps1:11 char:13
- Write-Error 'boo'
- ~~~~~~~~~~~~~~~~~
- CategoryInfo : NotSpecified: (:) [Write-Error], NotSupportedException
- FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.WriteErrorCommand
Dan Thompson:
In addition to being annoying for straight-up calling advanced functions (you can't use "-ErrorAction Ignore" with them), this also hampers meta-programming (you can't do "& $someCmd -ErrorAction Ignore", because you might not know if $someCmd is an advanced function or not).
Reacted by Alan Mervitz, Michael Klement, alx9r, Kris Borowinski, Mike, Tom--, Dan Thompson, DarkLite1, scott1138, wisemoth and 1 more
More specifically, I think what's going on is (disclaimer: haven't looked at the source code):
When an advanced function is called, the -ErrorActionparameter value is translated into the $ErrorActionPreferencevariable value in the scope of the function, presumably so as to propagate the setting to calls to other cmdlets made inside the same function.
The above is the cause of the problem: Ignore is not supported as a value of the preference variable, and the error message to that effect is triggered whenever something inside the advanced function writes to the error stream, including Write-Error itself.
A simplified example:
functionGet-Foo {
[CmdletBinding()] param ()
# Output the function-scope $ErrorActionPreference variable's value.# NOTE: Only set if -ErrorAction ... was passed.
(Get-Variable-Scope 0 ErrorActionPreference).Value
# Trigger an error; if -ErrorAction Ignore was passed, this will# provoke the spurious "The value Ignore is not supported for an ActionPreference variable."# error.1/0
}
Sourcing this function and invoking it as Get-Foo -ErrorAction Ignore shows the problem.
Reacted by Joel Bennett, alx9r, Jacob McIntosh, Dongbo Wang and wisemoth
Just because something was there for a long time
should never be an argument to decide a software development question.
It's just a question of a short time until any maintained Software gets a new release and in PowerShell, a Script can define the least expected runtime version.
So, it's no problem to let design errors disappear slowly and user-friendly :-)
Place the following statement at the start [of the begin block] of your advanced function:
if ($ErrorActionPreference-eq'Ignore') {
$ErrorActionPreference='Ignore'# create *local* variable with *string* value
}
This takes advantage of another bug, #3483:
If you create a preference variable in a non-global scope, it isn't type-constrained, so the local $ErrorActionPreference instance truly contains the string'Ignore'.
Despite being a string, the value does take effect and, because the check that causes the unwanted error expects an instance of the proper enumeration type, [System.Management.Automation.ActionPreference], the check is effectively suppressed.
I was just reading the code behind this, and I have to ask: given how common parameters work in PowerShell today, setting action preference variables to ensure that the desired behavior propagates to other commands, isn't this a PSScriptAnalyzer problem that is inappropriately being handled internally within PowerShell code?
// We don't want to support "Ignore" as action preferences, as it leads to bad
// scripting habits. They are only supported as cmdlet overrides.
That feels very wrong to me, and it gets in the way of being able to do something really useful (using -ErrorAction Ignore as appropriate when invoking advanced functions).
IMHO the best solution to this issue is to allow people to shoot themselves in the foot, but ensure that the tools they should be using (PSScriptAnalyzer directly or integrated into an editor like VS Code) properly flag that as red and identify that you should never set an action preference variable to Ignore, with proper guidance on how they should handle such things.
That solution fixes this issue, and is positioned to do a much better job educating the scripter so that they know better in the future.
Reacted by Michael Klement, Rain Sallow (/u/ta11ow) and Joey Aiello
Just adding to the chorus asking for a fix -- whatever the cause of the issue, the behavior makes no sense and hampers many scenarios. Please fix in PowerShell 6 and 7.
Activity
SteveL-MSFT commentedon Sep 29, 2016
TFS:6868128
joeyaiello commentedon May 24, 2017
This kinda stinks, but it's been there for a long time. I'm going to put it in the DevEx Project, and we can triage it against everything there.
mklement0 commentedon Dec 15, 2017
More specifically, I think what's going on is (disclaimer: haven't looked at the source code):
When an advanced function is called, the
-ErrorActionparameter value is translated into the$ErrorActionPreferencevariable value in the scope of the function, presumably so as to propagate the setting to calls to other cmdlets made inside the same function.The above is the cause of the problem:
Ignoreis not supported as a value of the preference variable, and the error message to that effect is triggered whenever something inside the advanced function writes to the error stream, includingWrite-Erroritself.A simplified example:
Sourcing this function and invoking it as
Get-Foo -ErrorAction Ignoreshows the problem.schittli commentedon Sep 13, 2018
Just because something was there for a long time
should never be an argument to decide a software development question.
It's just a question of a short time until any maintained Software gets a new release and in PowerShell, a Script can define the least expected runtime version.
So, it's no problem to let design errors disappear slowly and user-friendly :-)
mklement0 commentedon Nov 29, 2018
Yes, it would be nice to get that fixed soon.
In the meantime, here is a workaround:
Place the following statement at the start [of the
beginblock] of your advanced function:This takes advantage of another bug, #3483:
If you create a preference variable in a non-global scope, it isn't type-constrained, so the local
$ErrorActionPreferenceinstance truly contains the string'Ignore'.Despite being a string, the value does take effect and, because the check that causes the unwanted error expects an instance of the proper enumeration type,
[System.Management.Automation.ActionPreference], the check is effectively suppressed.3 remaining items
KirkMunro commentedon Apr 18, 2019
I was just reading the code behind this, and I have to ask: given how common parameters work in PowerShell today, setting action preference variables to ensure that the desired behavior propagates to other commands, isn't this a PSScriptAnalyzer problem that is inappropriately being handled internally within PowerShell code?
For reference, see this comment in ExecutionContext.cs.
PowerShell/src/System.Management.Automation/engine/ExecutionContext.cs
Lines 577 to 578 in d801544
That feels very wrong to me, and it gets in the way of being able to do something really useful (using
-ErrorAction Ignoreas appropriate when invoking advanced functions).IMHO the best solution to this issue is to allow people to shoot themselves in the foot, but ensure that the tools they should be using (PSScriptAnalyzer directly or integrated into an editor like VS Code) properly flag that as red and identify that you should never set an action preference variable to
Ignore, with proper guidance on how they should handle such things.That solution fixes this issue, and is positioned to do a much better job educating the scripter so that they know better in the future.
scott1138 commentedon Aug 18, 2019
Another use case - when running Pester tests it's useful to not have any output and let Pester handle the test case reporting.
adamedx commentedon Sep 25, 2019
Just adding to the chorus asking for a fix -- whatever the cause of the issue, the behavior makes no sense and hampers many scenarios. Please fix in PowerShell 6 and 7.
KirkMunro commentedon Sep 25, 2019
The fix for this was added to PowerShell 7 preview 4. This issue can be closed.
adamedx commentedon Sep 25, 2019
No 6 then? Whatever, I'll take it in 7 -- thanks!
KirkMunro commentedon Sep 25, 2019
Any changes to 6 at this point would only be made for security reasons.
adamedx commentedon Oct 22, 2019
yay
daverickdunn commentedon May 14, 2020
Still an issue in 7.1...
vexx32 commentedon May 14, 2020
Richard Dunn (@daverickdunn) I'm not seeing it in 7.1preview2; can you share what you're doing that's making that show up for you?
- Incorporate workaround for PowerShell/PowerShell#1759.
Fix Publish-BcContainerApp -sync failing on BC29 containers