Powershell: Parameter set names are unexpectedly case-sensitive

Created on 24 Nov 2019  路  2Comments  路  Source: PowerShell/PowerShell

Currently, a default parameter set in [CmdletBinding(DefaultParameterSetName='...')] is only correctly recognized as referring to a parameter set (implicitly) declared in [Parameter(ParameterSetName='...')] if the two identifiers match _case-exactly_, which is unexpected and can lead to subtle bugs.

Similarly, two [Parameter()] attributes (associated with different parameters) that name what is case-_insensitively_ the same parameter set name in reality create distinct parameter sets with their specific case variations.

Steps to reproduce

# OK: Make the parameter set names match case-exactly.
pwsh -noprofile -noninteractive -c {
    function foo {
      [CmdletBinding(DefaultParameterSetName='ById')]
      param (
        [Parameter(ParameterSetName='ById', Mandatory)] [int] $Id
      )
    }
    try { foo } catch { }
    $?
} | Should -Be $false

# Fails: The parameter set names match case-insensitively, but differ in actual case.
pwsh -noprofile -noninteractive -c {
    function foo {
      [CmdletBinding(DefaultParameterSetName='BYID')]
      param (
        [Parameter(ParameterSetName='ById', Mandatory)] [int] $Id
      )
    }
    try { foo } catch { }
    $?
} | Should -Be $false

Expected behavior

Both tests should pass, because the selection of parameter set ById should trigger a prompt for the mandatory $Id value, which should fail due to -noninteractive, making $? reflect $false

Actual behavior

The 2nd test fails:

Expected $false, but got $true.

That is, case variation BYID didn't select parameter set ById, but implicitly created a new BYID parameter set, which - due to lacking any parameters associated with it - quietly accepted invocation without arguments.

Environment data

PowerShell Core 7.0.0-preview.6
Issue-Bug WG-Engine

All 2 comments

More simple repo:

    function foo {
      [CmdletBinding(DefaultParameterSetName='BYID')]
      param (
        [Parameter(ParameterSetName='ById',position=0)] [int] $Id,
        [Parameter(ParameterSetName='BYID',position=0)] [int] $Id2
      )
"$id;$id2"
    }

foo 111

    function foo {
      [CmdletBinding(DefaultParameterSetName='BYID')]
      param (
        [Parameter(ParameterSetName='ById',position=0)] [int] $Id,
        [Parameter(ParameterSetName='qqq',position=0)] [int] $Id2
      )
"$id;$id2"
    }

foo 111

A PSSA rule is pending since 2015 :
https://github.com/PowerShell/PSScriptAnalyzer/issues/396

it's a bug that was referenced on MS Connect :
https://connect.microsoft.com/PowerShell/feedback/details/928085/parameterset-names-should-not-be-case-sensitive

Users get redirected to this page when they try to access Microsoft Connect.
Was this page helpful?
0 / 5 - 0 ratings