Skip to content

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

Closed

Description

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

Activity

  1. added
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Dec 2, 2019
  2. 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[/+] on Dec 2, 2019
  3. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    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.

  4. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    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.

  5. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    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.

  6. aolszowka commented on Nov 16, 2023

    @aolszowka

    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

  7. microsoft-github-policy-service commented on Nov 24, 2023

    @microsoft-github-policy-service
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-No ActivityIssue has had no activity for 6 months or moreWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions