Description
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/module/microsoft.powershell.core/about/about_functions?view=powershell-7.4#functions-with-parameters
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-7.4
Summary
While PowerShell allows a function parameter name to begin with a number, it should almost always be avoided.
Due to how -
followed by a number is parsed in argument mode, using the parameter in a normal manner isn't possible. PS users should be warned to avoid this type of naming as it makes code harder to call/reuse.
The issue is not apparent when writing the code/defining the command and may not be apparent to potential callers either.
Details
function TestFunction { param ([switch] $100, [string] $200) "100: $100"; "200: $200" }
{ TestFunction -100 }.Ast.EndBlock.Statements[0].PipelineElements[0].CommandElements[-1]
# StringConstantExpressionAst:
# StringConstantType : BareWord
# Value : -100
# StaticType : System.String
{ TestFunction -200 Foo }.Ast.EndBlock.Statements[0].PipelineElements[0].CommandElements[1, 2]
# StringConstantExpressionAst:
# StringConstantType : BareWord
# Value : -200
# StaticType : System.String
# StringConstantExpressionAst:
# StringConstantType : BareWord
# Value : Foo
# StaticType : System.String
-100
and -200
are both parsed as bareword (unquoted) arguments, not parameters. This limitation is mentioned in the Language Specification, albeit the first-parameter-char
syntax suggests PowerShell outright does not support parameter names beginning with a number, which isn't accurate.
A parameter can be named beginning with a number, it just can't be used normally.
One workaround is hash table splatting:
# Broken.
TestFunction -100
# 100: False
# 200: -100
# OK.
# Quoting the key isn't mandatory for this particular case, but is
# generally good practice when the intention is to specify a string.
$ht = @{ '100' = $true }
TestFunction @ht
# 100: True
# 200:
Another workaround, applicable to .ps1
script files, is to call the file with powershell.exe -File
or pwsh -File
, since the initial parsing of the parameter becomes irrelevant once the command line string is constructed by PS.
Suggested Fix
In about_Functions and about_Functions_Advanced_Parameters:
- Add a warning that it is generally best to avoid naming a parameter beginning with a number as using the parameter normally (
Command -Parameter
) isn't possible.- Note that this affects any parameter-supporting command type, not just functions.
- It applies to both advanced and non-advanced/simple commands.
- Make a note of the hash table splatting workaround in case the reader encounters someone else's code with this issue.