-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC Proposal: Allow execution preferences to persist beyond module or script scope #198
Comments
In my own scripts I have found that passing these flags as parameters leads to problems. A better approach is to use the environment variable and code scripts to use those. By using parameters we have to explicitly define and deal with those at the top of the script AND SET DEFAULTS. Yes we can set the default to the environment variable but then we have created more work for ourselves to get the same result. |
@jtmoree-kahalamgmt-com: That's actually not true. At the top of your script file, make sure you add the For example: @'
[CmdletBinding(SupportsShouldProcess)]
param()
'@ | Out-File .\t.ps1
Get-Command .\t.ps1 -Syntax
Remove-Item .\t.ps1 The output of that snippet will show you that the Given this is how PowerShell already works today, I don't see any benefit to using environment variables instead. |
One benefit of using env vars is that I don't have to put extra code at the top of my scripts. ;-) My OP may have been ambiguous. When I say 'have to set defaults' I mean that any defined parameter is defaulted to NULL. I don't want defaults in the local scope. I want values to come from the parent. For example, as we automate our processes and deploy the same code to dev/stage/live I am removing the 'parameters' and setting environment variables for each platform and prefs. This includes the debug and verbose prefs, etc. IMHO it takes more code use parameters by defining them in the scripts, setting whatever binding options, and then passing them on the calling command. Thanks for the tip on CmdletBinding. Might come in handy. |
Moved into PR #221. |
PowerShell has a long-standing issue where execution preferences such as those defined by the
-ErrorAction
,-WarningAction
,-InformationAction
,-Debug
,-Verbose
,-WhatIf
and-Confirm
common parameters, or those defined by any of the$*Preference
variables, do not persist from a module to another module or script, nor do they persist from a script to another module or script. This is a result of how modules and scripts are scoped within PowerShell. It impacts modules written by Microsoft as well as scripts and modules written by the community, and it is often identified as a bug when it shows up in various places. You can see some of the discussion around this in PowerShell Issue #4568.Regardless of whether you are authoring a script, an advanced function, or a cmdlet, you should be able to do so knowing that all execution preferences will be carried through the entire invocation of a command, end to end, regardless of the implementation details of that command. Cmdlets already work this way today. You can invoke cmdlets within a script, or within an advanced function defined in a module, and the execution preferences used during the invocation of that script or advanced function will be respected by the cmdlets that are invoked. This RFC is about making it possible for scripts or advanced functions to work that way as well.
It is important to note that the only way to implement this feature such that it is not a breaking change is by making it optional; however, even with it optional, it can be enabled by default for new modules to correct this problem going forward, and since it is optional, existing scripts and modules could be updated to support it as well, when they are ready to take on the responsibility of testing that out. That would allow this feature to be adopted more easily for new modules, while existing modules could be updated over time. While we have experimental feature support, those are for a different purpose so an additional RFC is being published at the same time as this RFC to add support for optional feature definition in PowerShell (see the RFC proposal for optional features in PowerShell).
Motivation
As a scripter or a command author,
I can invoke commands without having to care what type of command (cmdlet vs advanced function) I am invoking,
So that I can can focus on my script without having to worry about the implementation details of commands I use.
As a command author,
I can change a published command from an advanced function to a cmdlet or vice versa if needed without worrying about invocation nuances in PowerShell,
So that I can focus on what is the best way to code my commands for myself and my team.
User experience
Specification
To resolve this problem, a new optional feature called
PersistCommandExecutionPreferences
would be defined in PowerShell. When this feature is enabled in a script or module, it would change how common parameters work in that script or module.Today if you invoke a script or advanced function with
-ErrorAction
,-WarningAction
,-InformationAction
,-Debug
,-Verbose
,-WhatIf
, or-Confirm
, the corresponding$*Preference
variable will be set within the scope of that command. That behaviour will remain the same; however when the optional feature is enabled, in addition to that behaviour, the names and values you supplied to those common parameters stored in a newExecutionPreferences
dictionary property of the$PSCmdlet
instance. Once$PSCmdlet.ExecutionPreferences
is set, any common parameters that are stored in$PSCmdlet.ExecutionPreferences
that are not explicitly used in the invocation of another command within that command scope will be automatically passed through if the command being invoked supports common parameters.It is important to note that parameter/value pairs in
$PSCmdlet.ExecutionPreferences
, which represent command execution preferences, would take priority and be applied to a command invocation before values in$PSDefaultParameterValues
, which represents user/module author parameter preferences (i.e. if both dictionaries have a value to be applied to a common parameter, only the value in$PSCmdlet.ExecutionPreferences
would be applied).As per the optional feature specification, the optional feature can be enabled in a module manifest (see example above), or a script file via
#requires
. For more details on how that works, see the RFC proposal for optional features in PowerShell.Alternate proposals and considerations
Rip off the bandaid
Some members of the community feel it would better to break compatibility here. On the plus side, not having to deal with this an an optional parameter would be ideal; however, to increase adoption of PowerShell 7, it would be better to make the transition from PowerShell 5.1 into 7 easier by having as few breaking changes as possible.
One way to achieve this while supporting users who don't want the breaking change would be to inverse the optional feature, where the breaking change is in place and users opt out of the breaking change instead of opting into it. Another way would be to change the optional feature design such that users can turn them off in scripts/modules if those scripts/modules are not ready to use the breaking change. See the Alternate Proposals and Considerations section of the RFC proposal for optional features in PowerShell for more information.
Support
-DebugAction
,-VerboseAction
, and-ProgressAction
if those common parameters are addedThe RFC proposal for ScriptBlocks to handle non-terminating message processing suggests that we consider adding
-DebugAction
,-VerboseAction
, and-ProgressAction
common parameters. These are important to consider adding, because beyond the-Debug
and-Verbose
switch common parameters (which only supportActionPreference.Continue
), the new common parameters would be the only way to propagate execution preferences for debug, verbose, and progress messages to all commands that are invoked.The text was updated successfully, but these errors were encountered: