Skip to content
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

Binding a parameter via the pipeline can break implicit parameter-set selection #11235

Closed
mklement0 opened this issue Dec 2, 2019 · 5 comments
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-No Activity Issue has had no activity for 6 months or more WG-Engine core PowerShell engine, interpreter, and runtime

Comments

@mklement0
Copy link
Contributor

mklement0 commented Dec 2, 2019

@ili101 discovered that binding a parameter via the pipeline can cause PowerShell to select the wrong parameter set under certain circumstances.

The issue can be resolved by designating a default parameter set.

Arguably, PowerShell shouldn't pick a default parameter set at all in this case, but it does:

  • defensibly with direct arguments,
  • seemingly incorrectly with conceptually equivalent pipeline input

Note that it is legitimate use case to have an explicit parameter set that has no mandatory parameter (set A below): You may want to group multiple parameters as logically related, even if none of them is individually mandatory.

Steps to reproduce

function foo
{
  [CmdletBinding()] # DefaultParameterSetName='A' would make the issue go away
  Param(
    [Parameter(ParameterSetName = 'A')]            $A1,
    [Parameter(ParameterSetName = 'A')]            $A2,
    [Parameter(ParameterSetName = 'B', Mandatory)] $B1,
    [Parameter(ParameterSetName = 'B')]            $B2,
    [Parameter(ValueFromPipeline)]                 $InputObject
  )
  $PSCmdlet.ParameterSetName
}

# OK: Argument-less invocation selects 'A'
foo  | Should -Be A
# OK: Binding -InputObject by direct argument also selects 'A' 
foo -InputObject 1 | Should -Be A
# FAILS: Binding -InputObject via the pipeline inexplicably selects 'B'
# Just press Enter to answer the prompt.
& { 1 | foo }      | Should -Be A

Expected behavior

All tests should pass.

Actual behavior

The 3rd test fails: It unexpectedly selects set B prompts for a value for -B1.

Expected strings to be the same, but they were different. 
String lengths are both 1. Strings differ at index 0. 
Expected: 'A' But was:  'B'

Environment data

PowerShell Core 7.0.0-preview.6
@mklement0 mklement0 added the Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a label Dec 2, 2019
@mklement0 mklement0 changed the title Binding a parameter via the pipeline can break parameter-set selection Binding a parameter via the pipeline can break implicit parameter-set selection Dec 2, 2019
@iSazonov iSazonov added the WG-Engine core PowerShell engine, interpreter, and runtime label Dec 5, 2019
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

2 similar comments
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

@microsoft-github-policy-service microsoft-github-policy-service bot added Resolution-No Activity Issue has had no activity for 6 months or more labels Nov 16, 2023
@aolszowka
Copy link

Still repros for me; following exactly what this user has written:

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.9
PSEdition                      Core
GitCommitId                    7.3.9
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}       
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
function foo {
    [CmdletBinding()] # DefaultParameterSetName='A' would make the issue go away
    Param(
        [Parameter(ParameterSetName = 'A')]            $A1,
        [Parameter(ParameterSetName = 'A')]            $A2,
        [Parameter(ParameterSetName = 'B', Mandatory)] $B1,
        [Parameter(ParameterSetName = 'B')]            $B2,
        [Parameter(ValueFromPipeline)]                 $InputObject
    )
    $PSCmdlet.ParameterSetName
}

# OK: Argument-less invocation selects 'A'
foo
# OK: Binding -InputObject by direct argument also selects 'A'
foo -InputObject 1
# FAILS: Binding -InputObject via the pipeline inexplicably selects 'B'
# Just press Enter to answer the prompt.
& { 1 | foo }

image

Copy link
Contributor

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-No Activity Issue has had no activity for 6 months or more WG-Engine core PowerShell engine, interpreter, and runtime
Projects
None yet
Development

No branches or pull requests

3 participants