Skip to content

Misleading parameter shorthand name example #12606

@surfingoldelephant

Description

@surfingoldelephant

Prerequisites

  • Existing Issue: Search the existing issues for this repository. If there is an issue that fits your needs do not file a new one. Subscribe, react, or comment on that issue instead.
  • Descriptive Title: Write the title for this issue as a short synopsis. If possible, provide context. For example, "Typo in Get-Foo cmdlet" instead of "Typo."
  • Verify Version: If there is a mismatch between documentation and the behavior on your system, ensure that the version you are using is the same as the documentation. Check this box if they match or the issue you are reporting is not version specific.

Links

https://learn.microsoft.com/en-us/powershell/scripting/learn/shell/using-aliases

Summary

The shorthand name example incorrectly suggests that -Rec is the shortest name to uniquely identify Get-ChildItem -Recurse.

Details

Parameter aliases and shorthand names states the following:

For example, the Get-ChildItem cmdlet has the Recurse and ReadOnly parameters. To uniquely identify the Recurse parameter, you only need to provide -Rec.

This is misleading. Get-ChildItem -r works in all PS versions as shorthand for Get-ChildItem -Recurse. -Rec is not required.

  1. -ReadOnly is a dynamic parameter. Shorthand names are bound before dynamic parameters are considered, so there's no ambiguity.

    function Test {
    
        [CmdletBinding()]
        param ([string] $Foo)
    
        dynamicparam {
            $paramAttr      = [Management.Automation.ParameterAttribute] @{ Mandatory = $false }
            $attrCollection = [Collections.ObjectModel.Collection[Attribute]]::new()
            $attrCollection.Add($paramAttr)    
          
            $parameter     = [Management.Automation.RuntimeDefinedParameter]::new('Far', [string], $attrCollection)
            $parameterDict = [Management.Automation.RuntimeDefinedParameterDictionary]::new()
            $parameterDict.Add($parameter.Name, $parameter)
    
            $parameterDict
        }
    
        end {
            $PSBoundParameters
        }
    }
    
    Test -f a
    # Key Value
    # --- -----
    # Foo a
    
    Test -f a -fa b
    # Key Value
    # --- -----
    # Foo a
    # Far b
  2. Even if -ReadOnly wasn't a dynamic parameter, Get-ChildItem -r would still work in PS v7.5+ due to -r being added as an alias of -Recurse. Parameter aliases always take priority.

    function Test { 
    
        [CmdletBinding()] 
        param (
            [Parameter()] 
            [Alias('f')] 
            $Foo, 
    
            $Far
        ) 
    
        $PSBoundParameters 
    }
    Test -f a
    
    # Key Value
    # --- -----
    # Foo a

Suggested Fix

Replace the Get-ChildItem -Recurse/-r example with Get-ChildItem -Force/-f.

  • Get-ChildItem -f is truly ambiguous.
  • Get-ChildItem -fo can be used as shorthand for -Force and Get-ChildItem -fi as shorthand for -Filter.
  • It's worth noting that -f, -fi and -fil doesn't create ambiguity with -File because -File is a dynamic FileSystem provider parameter.
    • -fi and -fil specify -Filter. The only way to specify -File is with -File.
Get-Childitem -f
# Get-ChildItem: Parameter cannot be processed because the parameter name 'f' is ambiguous. 
# Possible matches include: -Filter -Force.

Get-ChildItem -Path C:\ -fo
# OK; gets hidden items.

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-doc-bugIssue - error in documentationneeds-triageWaiting - Needs triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions