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
Aside from closely (but not exactly, see below) mirroring what is already in place internally for experimental features in PowerShell, this RFC includes a few additional enhancements that will be useful for optional features, as follows:
136
+
Unlike experimental features, which can only be enabled or disabled in PowerShell sessions created after enabling or disabling them, optional features can be enabled or disabled in the current PowerShell session as well as in future PowerShell sessions. This is necessary to allow certain functionality to be "lit up" in packaged modules or scripts.
137
+
138
+
Below you will find details describing how this functionality will be implemented.
139
+
140
+
### System and User scope powershell.config.json
141
+
142
+
Enabling optional features automatically in future PowerShell sessions requires creating or updating one of two `powershell.config.json` configuration files that are read on startup of a new PowerShell session:
143
+
144
+
* one in `$PSHOME`, which applies to all user sessions
145
+
* one in `$HOME\Documents\PowerShell\powershell.config.json` on Windows or `$HOME/.config/powershell/powershell.config.json` on Linux and macOS, which applies only to current user sessions.
146
+
147
+
This RFC will enable optional feature defaults to be read from these configuration files, with current user configuration taking precedence over system (all users) configuration. System config is not policy so this should be acceptable and expected.
106
148
107
149
### Add parameter to New-ModuleManifest
108
150
109
-
`[-OptionalFeatures <string[]>]`
151
+
`[-OptionalFeatures <object[]>]`
110
152
111
-
This new parameter would assign specific optional features to new modules. Note that these would be in addition to optional features that are enabled by default in manifests created with `New-ModuleManifest`.
153
+
This parameter would configure specific optional features in the new module manifest that is generated.
112
154
113
-
### Add parameter to #requires statement
155
+
The values provided to this parameter would be combined with optional features that are enabled or disabled by default according to the session configuration files, with the values specified in the `New-ModuleManifest` command overriding the settings for optional features with the same name that are configured in the configuration files. Entries in this collection would either be string (the name of the optional feature to enable) or a hashtable with two keys: `name` (a string) and `enabled` (a boolean value). The hashtable allows an optional feature to be specifically disabled instead of enabled within a module, which is necessary if an older module does not support a newer optional feature yet.
114
156
115
-
`#requires -OptionalFeatures <string[]>`
157
+
A terminating error is generated if the same optional feature name is used twice in the collection passed into the `-OptionalFeatures` parameter.
116
158
117
-
This new parameter would enable optional features in the current script file.
159
+
### Add parameter set to #requires statement
118
160
119
-
### New command: Get-OptionalFeature
161
+
`#requires -OptionalFeatures <object[]>`
162
+
163
+
This parameter set would enable optional features in the current script file.
164
+
165
+
Entries in this collection would either be string (the name of the optional feature to enable) or a hashtable with two keys: `name` and `enabled`. The hashtable allows an optional feature to be specifically disabled instead of enabled within a script.
166
+
167
+
A terminating error is generated if the same optional feature name is used twice in the collection passed into the `-OptionalFeatures` parameter.
This command would return the optional features that are available in PowerShell. The default output format would be of type table with the properties `Name`, `Source`, and `Description`, and with the results grouped by the value of the `EnableIn` property. All of those properties would be of type string except for `EnabledIn`, which would be an enumeration with the possible values of `NotEnabled`, `Session`, `Manifest`, `Script`, and `Scope`. This differs from experimental features where `Enabled` is a boolean value. Given the locations in which an optional feature can be enabled, it would be more informative to identify where it is enabled than simply showing `$true` or `$false`. The enumeration values have the following meaning:
175
+
This command would return the current configuration of optional features that are available in PowerShell, read from the configuration files.
126
176
127
-
|Value|Description|How to set the feature up this way|
128
-
|--|--|--|
129
-
|NotEnabled|The optional feature is not enabled at all|Disable-OptionalFeature command|
130
-
|Session|The optional feature is enabled by default in all PowerShell sessions|Enable-OptionalFeature command|
131
-
|Manifest|The optional feature is enabled in the manifest for the current module|OptionalFeatures entry in module manifest|
132
-
|Script|The optional feature is enabled in the current script|#requires entry in script file|
133
-
|Scope|The optional feature is enabled the current scope|Use-OptionalFeature command|
177
+
The properties on the `S.M.A.OptionalFeatureConfiguration` object would be `Name`, `Session`, `NewManifest`, and `Scope`, defined as follows:
134
178
135
-
### New command: Enable-OptionalFeature
179
+
|Property Name|Description|
180
+
|--|--|
181
+
|`Name`|A string value that identifies the optional feature name|
182
+
|`Session`|A boolean value that identifies whether the optional feature is enabled or disabled in the current and new PowerShell sessions|
183
+
|`NewManifest`|A boolean value that identifies whether the optional feature is enabled or disabled in manifests created by new module manifests in the current and new PowerShell sessions|
184
+
|`Scope`|An enumeration identifying whether the optional feature configuration was set up for the `CurrentUser` or `AllUsers`|
185
+
186
+
The default output format is of type table with the properties `Name`, `Session`, and `NewManifest` with the results grouped by `Scope`.
187
+
188
+
When this command is invoked with the `-UserScope` parameter, the results are automatically filtered for that scope. The default value for `-UserScope` is `Any`, showing configuration values from both configuration files.
This command would enable an optional feature either globally (if the `-NewModuleManifests` switch is not used) or only in new module manifests created by `New-ModuleManifest`.
196
+
This command will return a list of the optional features that are available in PowerShell, along with their source and description.
197
+
198
+
The properties on the `S.M.A.OptionalFeature` object would be `Name`, `Source`, `Description`, defined as follows:
142
199
143
-
### New command: Disable-OptionalFeature
200
+
|Property Name|Description|
201
+
|--|--|
202
+
|`Name`|A string value that identifies the optional feature name|
203
+
|`Source`|A string value that identifies the area of PowerShell that is affected by this optional feature|
204
+
|`Description`|A string value that describes the optional feature|
205
+
206
+
The default output format would be of type table with the properties `Name`, `Source`, and `Description`.
207
+
208
+
### Enabling and disabling optional features in current and future PowerShell sessions
This command would disable an optional feature either globally (if the `-NewModuleManifests` switch is not used) or only in new module manifests created by `New-ModuleManifest`. If the optional feature is not enabled that way in the first place, nothing would happen.
216
+
It is important to note up front that there are three default states for an optional feature: enabled by default, implicitly disabled by default, and explicitly disabled by default. The only time an optional feature needs to be explicitly disabled by default is if it is enabled by default in the AllUsers configuration file and a specific user wants to disable it for their sessions. This impacts how `Disable-OptionalFeature` works.
217
+
218
+
The `Enable-OptionalFeature` command will enable an optional feature in current and future PowerShell sessions either globally (if the `-NewModuleManifests` switch is not used) or only in manifests created by `New-ModuleManifest`.
219
+
220
+
The `Disable-OptionalFeature` command will disable an optional feature in current and future PowerShell sessions either globally (if the `-NewModuleManifests` switch is not used) or only in manifests created by `New-ModuleManifest`. If the `AllUsers` scope is used and the optional feature is completely disabled in that scope as a result of this command, the entry is removed from the configuration file. If the `AllUsers` scope is used and there is no entry in the system (all users) configuration file, nothing happens. If the `CurrentUser` scope is used there is no entry in the system (all users) or current user configuration files, nothing happens. If the `CurrentUser` scope is used and the optional feature is enabled in the `AllUsers` configuration file, users will be informed that this feature is enabled for all users and asked to confirm that they want to explicitly disable this feature for the current user in the current and future PowerShell sessions. They can always re-enable it later.
This command would enable an optional feature for the duration of the `ScriptBlock` identified in the `-ScriptBlock` parameter, and return the feature to its previous state afterwards. This allows for easy use of an optional feature over a small section of code.
158
229
159
-
##Alternate proposals and considerations
230
+
### Checking optional feature states within the PowerShell runtime
160
231
161
-
### Extend experimental features to support the enhancements defined in this RFC
162
-
163
-
Experimental features and optional features are very similar to one another, so much so that they really only differ in name. Given the model for how both of these types of features are used, it may make sense to have them both use the same functionality when it comes to enabling/disabling them in scripts and modules. The downside I see to this approach is that optional features are permanent features in PowerShell while experimental features are not, so it may not be a good idea to support more permanent ways to enable experimental features such as `#requires` or enabling an experimental feature in a new module manifest.
164
-
165
-
### Supporting a `-Scope` parameter like the experimental feature cmdlets do
232
+
Optional features can be enabled or disabled in a session, module, script, or script block. Since enabling or disabling an optional feature can happen at different levels, the current state of an optional feature should be maintained in a stack, where the validation logic simply peeks at the top of the stack to see if the feature is enabled or not, popping the top of the stack off when appropriate (when leaving the scope of the module, script, or script block where the feature is enabled).
166
233
167
-
The `Enable-OptionalFeature`and `Disable-OptionalFeature` cmdlets could support a `-Scope` parameter like their experimental feature cmdlet counterparts do. I felt it was better to remove this for optional features, because it may be risky to allow a command to enable an optional feature in a scope above the one in which it is invoked, influencing behaviour elsewhere.
234
+
## Alternate proposals and considerations
168
235
169
-
### Allow optional features to be disabled at a certain level
236
+
### Extend experimental features to support the enhancements defined in this RFC
170
237
171
-
Certain optional features may be so important that PowerShell should be installed with them to be on by default. In cases where this happens, scripters should be able to indicate that they want the opposite behaviour in a script file or module, so that they can ensure any compatibility issues are addressed before the feature is enabled in that module/script. With this in mind, we could either allow optional features to be disabled at a certain level, or stick with enable only, inversing how the optional feature is designed such that turning it on effectively disables a breaking fix that was deemed important enough to have fixed by default.
238
+
At a glance, experimental features and optional features are very similar to one another, so it was proposed that it may make sense to have them both use the same functionality when it comes to enabling/disabling them in scripts and modules; however, experimental features have a completely different intent (to try out new functionality in a PowerShell session), are only for future PowerShell sessions, and they only have a single on/off state. On the other hand, optional features are for the current and future PowerShell sessions, and may be enabled or disabled in various scopes within those sessions. For that reason, this approach doesn't seem like a viable solution. If we want to change that, perhaps someone should file an RFC against experimental features to make that change.
0 commit comments