Title: Allow explicitly specified named parameter to supersede the one from hashtable splatting · Issue #13114 · PowerShell/PowerShell · GitHub
Open Graph Title: Allow explicitly specified named parameter to supersede the one from hashtable splatting · Issue #13114 · PowerShell/PowerShell
X Title: Allow explicitly specified named parameter to supersede the one from hashtable splatting · Issue #13114 · PowerShell/PowerShell
Description: Problem Statement Today, the splatting of a Hashtable in a PowerShell command invocation works just like explicitly specifying those key-value pairs as individual named parameters in the command line, so the following example doesn't wor...
Open Graph Description: Problem Statement Today, the splatting of a Hashtable in a PowerShell command invocation works just like explicitly specifying those key-value pairs as individual named parameters in the command li...
X Description: Problem Statement Today, the splatting of a Hashtable in a PowerShell command invocation works just like explicitly specifying those key-value pairs as individual named parameters in the command li...
Opengraph URL: https://github.com/PowerShell/PowerShell/issues/13114
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Allow explicitly specified named parameter to supersede the one from hashtable splatting","articleBody":"### Problem Statement\r\n\r\nToday, the splatting of a Hashtable in a PowerShell command invocation works just like explicitly specifying those key-value pairs as individual named parameters in the command line, so the following example doesn't work:\r\n```powershell\r\n$common = @{\r\n AddressPrefix = \"10.0.0.0/16\"\r\n ResourceGroupName = \"MyResourceGroup\"\r\n Location = \"westus\"\r\n}\r\n\r\nNew-AzVirtualNetwork @common -Name MyNet -AddressPrefix \"10.0.0.0/24\"\r\n\r\n\u003e New-AzVirtualNetwork: Cannot bind parameter because parameter 'AddressPrefix' is specified more than once. To provide \r\n\u003e multiple values to parameters that can accept multiple values, use the array syntax. For example, \"-parameter \r\n\u003e value1,value2,value3\".\r\n```\r\n`$common` may work well for all other 99 `New-AzVirtualNetwork` calls in my scripts, but there is one instance where a different address prefix is required. In such a case, I would have to temporarily change the Hashtable and restore it after the invocation, like this:\r\n```powershell\r\ntry {\r\n $commonAddrPrefix = $common.AddressPrefix\r\n $common.AddressPrefix = \"10.0.0.0/24\"\r\n\r\n New-AzVirtualNetwork @common -Name MyNet\r\n}\r\nfinally {\r\n $common.AddressPrefix = $commonAddrPrefix\r\n}\r\n```\r\n\r\n### Proposed technical implementation details\r\n\r\nThe proposal is to allow an explicitly specified named parameter to supersede _the same one_ that is expanded from splatting a Hashtable.\r\n\r\n1. To be clear, I want to point out that the proposal targets _\"Hashtable splatting\"_ and _\"explicitly specified named parameters\"_ only.\r\n (a). Array splatting won't change its current behavior.\r\n (b). Hashtable splatting won't change its current behavior when working with explicitly specified positional parameters.\r\n (c). Both Array splatting and Hashtable splatting keep their current behaviors when working with native command.\r\n\r\n1. The `CommandParameterInternal` created from [splatting a Hashtable](https://github.com/PowerShell/PowerShell/blob/babf02768bec3ab11c5991b5c2b3603256bad43a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs#L340) needs to be marked as _came-from-splatting_.\r\n\r\n1. To determine whether 2 named parameters are _the same_, parameters need to be resolved to cover the use of parameter alias or prefix (e.g. `-s` for `-Seconds` in `Start-Sleep`), so the work should be done in the parameter binder.\r\n\r\n1. Script-block-to-PowerShell conversion also [does splatting](https://github.com/PowerShell/PowerShell/blob/babf02768bec3ab11c5991b5c2b3603256bad43a/src/System.Management.Automation/engine/runtime/ScriptBlockToPowerShell.cs#L736). It calls `powershell.AddParameter(string paramName, object paramValue)` for each of the key-value pair of the Hashtable. The _\"came-from-splatting\"_ message needs to be passed on to the `PowerShell` instance, so we will need to add a boolean property `CamFromSplatting` to [`CommandParameter`](https://github.com/PowerShell/PowerShell/blob/babf02768bec3ab11c5991b5c2b3603256bad43a/src/System.Management.Automation/engine/CommandParameter.cs#L13) to track that information, which will be used when invoking the `PowerShell` instance.\r\n\r\n1. __Challenge:__ the script-block-to-PowerShell conversion is also used in remoting scenario [when the script block to invoke on the remote side contains command invocations only](https://github.com/PowerShell/PowerShell/blob/babf02768bec3ab11c5991b5c2b3603256bad43a/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs#L2298), for example `Invoke-Command { param($hash) dir @hash } -ArgumentList @{ path = \"c:\\\" }`. In that case, the generated `PowerShell` instance will be used to create a remote pipeline and run on the remote side, so the new member added to `CommandParameter` will likely cause serialization/deserialization problems. More investigation is needed.\r\n\r\n**Update to (5):** powershell committee agreed (https://github.com/PowerShell/PowerShell/issues/13108#issuecomment-655794760) to not use `GetPowerShell` in remote command execution, so (5) won't be a blocker.\r\n\r\n/cc @SteveL-MSFT @JamesWTruher @joeyaiello \r\n","author":{"url":"https://github.com/daxian-dbw","@type":"Person","name":"daxian-dbw"},"datePublished":"2020-07-06T00:22:23.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/13114/PowerShell/issues/13114"}
| 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:31eb22f0-3a70-22f2-c1c8-b541cfedc7e6 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E8C2:1A17AB:1224B3:1A9791:6A5767A6 |
| html-safe-nonce | e953f870788bb79c65e219876c97478491f00ab8ef1d6e283bf25c38c75ca047 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFOEMyOjFBMTdBQjoxMjI0QjM6MUE5NzkxOjZBNTc2N0E2IiwidmlzaXRvcl9pZCI6IjU5MTkxMTExMjIwOTE3MzA4NTUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 1d435334b12ef5d352d22344a81a31d9b86e5a5d896100cafb7f6f198882f507 |
| hovercard-subject-tag | issue:651175562 |
| 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/13114/issue_layout |
| twitter:image | https://opengraph.githubassets.com/7d32defdb860ae53b543b15070656c9c712e272936a7034cb057bd166a0a78cf/PowerShell/PowerShell/issues/13114 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/7d32defdb860ae53b543b15070656c9c712e272936a7034cb057bd166a0a78cf/PowerShell/PowerShell/issues/13114 |
| og:image:alt | Problem Statement Today, the splatting of a Hashtable in a PowerShell command invocation works just like explicitly specifying those key-value pairs as individual named parameters in the command li... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | daxian-dbw |
| hostname | github.com |
| expected-hostname | github.com |
| None | 4e7a7296a3830877cf21a6ad2a972c9e618a48915e03966cf0c53eb08e5aad98 |
| 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 | 1b5a9c55f39dd27607a574cdc272552f20236b44 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width