Title: Treat `-Switch:$false` the same as omitting a switch when selecting a parameter set · Issue #25027 · PowerShell/PowerShell · GitHub
Open Graph Title: Treat `-Switch:$false` the same as omitting a switch when selecting a parameter set · Issue #25027 · PowerShell/PowerShell
X Title: Treat `-Switch:$false` the same as omitting a switch when selecting a parameter set · Issue #25027 · PowerShell/PowerShell
Description: Summary of the new feature / enhancement Note: The problem affects cmdlets that use [switch] parameters as mandatory in the context of an explicit parameter set, such as Get-UpTime See #25015 In short: What this issue proposes is to trea...
Open Graph Description: Summary of the new feature / enhancement Note: The problem affects cmdlets that use [switch] parameters as mandatory in the context of an explicit parameter set, such as Get-UpTime See #25015 In sh...
X Description: Summary of the new feature / enhancement Note: The problem affects cmdlets that use [switch] parameters as mandatory in the context of an explicit parameter set, such as Get-UpTime See #25015 In sh...
Opengraph URL: https://github.com/PowerShell/PowerShell/issues/25027
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Treat `-Switch:$false` the same as omitting a switch when selecting a parameter set","articleBody":"### Summary of the new feature / enhancement\n\nNote:\n\n* The problem affects cmdlets that use `[switch]` parameters as _mandatory_ in the context of an explicit parameter set, such as `Get-UpTime`\n * See #25015\n * In short: What this issue proposes is to treat `-Switch:$false` as if `-Switch` had _not_ been specified, as these two forms should generally be equivalent, with the former often being used for _programmatically_ building arguments, especially via splatting.\n * Indeed, checking `$Switch.IsPresent` yields `$false` in _both_ cases (for thoughts about the naming of this property, see [this comment](https://github.com/PowerShell/PowerShell/issues/25015#issuecomment-2659902287)).\n * Currently, `-SomeSwitch:$false` acts the same as passing `-SomeSwitch` (i.e., implied `:$true`) in terms of _parameter-set selection_, which causes all cmdlets that only check whether the relevant parameter set was selected to in effect _ignore_ the `$false` argument.\n * @MartinGC94's analysis [here](https://github.com/PowerShell/PowerShell/issues/25015#issuecomment-2659999347) shows that quite a few existing cmdlets misbehave in this way, and the proposal at hand would presumably automatically fix that.\n \n* It is debatable whether this proposal should be considered a feature request or a bug report.\n \n* Either way, it is technically a breaking change, but - given the counterintuitive behavior and the presumed rarity of passing negated switches (`-SomeSwitch:$false`), it hopefully falls into [bucket 3](https://github.com/PowerShell/PowerShell/blob/master/docs/dev-process/breaking-change-contract.md#bucket-3-unlikely-grey-area)\n * In the vast majority of cases, _omitting_ `-SomeSwitch` and passing `-SomeSwitch:$false` (which is the only way to emulate omitting the switch when _splatting_ is used, short of conditionally constructing the splatting hashtable iteratively) should be considered equivalent.\n * (In edge cases, where `-SomeSwitch:$false` is designed to override a default value set _elsewhere_, notably via a preference variable (e.g., `-Confirm:$false` overriding the `$ConfirmPreference` variable), a different approach is already necessary, namely if, in addition to `$Switch.IsPresent` returning `$false` (which _is_ the case when `-Switch:$false` is passed), whether this \"non-presence\" was _explicitly signaled_ via a `-Switch:$false` argument rather than being implied by omission.)\n\n\n\nTo illustrate the problem:\n\n```powershell\nfunction foo {\n [CmdletBinding(DefaultParameterSetName='NoSwitchSet')]\n param(\n [Parameter(ParameterSetName='SwitchSet')]\n [switch] $Switch\n )\n [pscustomobject] @{\n SwitchValue = $Switch\n ParameterSetName = $PSCmdlet.ParameterSetName\n }\n}\n\n# Invocation without -Switch\nfoo \n# Invocation with negated -Switch, which _should_ be equivalent.\nfoo -Switch:$false\n# Ditto, via splatting\n$splat = @{ Switch = $false }\nfoo @splat\n```\n\nExpected / proposed behavior:\n\n```none\nSwitchValue ParameterSetName\n----------- ----------------\nFalse NoSwitchSet\nFalse NoSwitchSet\nFalse NoSwitchSet\n```\n\nCurrent behavior:\n\n```none\nSwitchValue ParameterSetName\n----------- ----------------\nFalse NoSwitchSet\nFalse SwitchSet\nFalse SwitchSet\n```\n\nThat is, the `-Switch:$false` invocations (whether directly or via splatting) unexpectedly still selected the `SwitchSet` parameter set.\n\n\n\n### Proposed technical implementation details (optional)\n\n_No response_","author":{"url":"https://github.com/mklement0","@type":"Person","name":"mklement0"},"datePublished":"2025-02-15T15:36:36.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":23},"url":"https://github.com/25027/PowerShell/issues/25027"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:9fc67cdf-6dd0-0377-9bba-745b2fb40e44 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8546:310BDB:264B445:34A3430:6A4EF310 |
| html-safe-nonce | c28bb5c351d12a5392973920fa0c3f475f5ba1699e86ecc14847828c4e799e96 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4NTQ2OjMxMEJEQjoyNjRCNDQ1OjM0QTM0MzA6NkE0RUYzMTAiLCJ2aXNpdG9yX2lkIjoiOTI5NzAyNzI3MzQ4MzE4OTkyIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | f25accbd81e4d7ba4e1192df27ad01bc0dbafebb4a8f6fc9d582f5198ddd60c0 |
| hovercard-subject-tag | issue:2855544102 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/PowerShell/PowerShell/25027/issue_layout |
| twitter:image | https://opengraph.githubassets.com/450bb9238aaa527a3c8884013b537c7dadf1f72cdd9e7500d2d024f5caec686f/PowerShell/PowerShell/issues/25027 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/450bb9238aaa527a3c8884013b537c7dadf1f72cdd9e7500d2d024f5caec686f/PowerShell/PowerShell/issues/25027 |
| og:image:alt | Summary of the new feature / enhancement Note: The problem affects cmdlets that use [switch] parameters as mandatory in the context of an explicit parameter set, such as Get-UpTime See #25015 In sh... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | mklement0 |
| hostname | github.com |
| expected-hostname | github.com |
| None | b92d11c0aa4a77d54ef4af1078b6a15fb5a70a215b30c4ecf28889d5a8e656d9 |
| turbo-cache-control | no-preview |
| go-import | github.com/PowerShell/PowerShell git https://github.com/PowerShell/PowerShell.git |
| octolytics-dimension-user_id | 11524380 |
| octolytics-dimension-user_login | PowerShell |
| octolytics-dimension-repository_id | 49609581 |
| octolytics-dimension-repository_nwo | PowerShell/PowerShell |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 49609581 |
| octolytics-dimension-repository_network_root_nwo | PowerShell/PowerShell |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 2b8f23afb982271f1b22258a94aede67a6b77760 |
| ui-target | canary-2 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width