Does PowerShell do some sort of nearest match or autocompletion when dealing with arguments passed to a script? Given this code...
[CmdletBinding()]
Param(
[string][Alias("aS")] $applySet,
[string][Alias("cS")] $conformSet,
[string][Alias("sL")] $setList,
[Parameter(ValueFromRemainingArguments = $true)][Object[]]$extraParameters = @()
)
Write-Host "s: $set"
Write-Host "sL: $setList"
Write-Host "aS: $applySet"
Write-Host "cS: $conformSet"
Write-Host "X: $extraParameters"
If I use -junk "junk" in the script shortcut I get that info in $extraParameters
as expected. Misspelling something, say -aplySet, also shows up as an extra parameter. However, using -set actually populates the $setList
variable rather than $extraParameters
as I would expect.
Verified in PowerShell 2.0 and 5.1. Any thoughts?
It is somewhat undocumented, as far as I can tell.
about_Parameters
doesn't mention the use of abbreviated parameters.about_Command_Syntax
talks about using parameters but not short versions.Save-Help
'd all the help and In PowerShell 1.0, part of the parameter name resolution logic includes support for identifying parameters by the shortest substring that uniquely identifies the parameter or an alias to the parameter when compared with a list of parameters and aliases for the cmdlet.
and it's mentioned in PowerShell developer Bruce Payette's book 'PowerShell In Action', chapter 2, P.39-40:
The piece of the PowerShell interpreter that figures all of this out is called the parameter binder. The parameter binder is smart - it doesn’t require that you specify the full name of a parameter as long as you specify enough for it to uniquely distinguish what you mean.
But that's it, no comment on design choice or rationale that I can see. Speculating, as @Mike Shepard comments, PowerShell's dual role as an interactive shell (where people want to type as little as possible, and are writing one-off throwaway commands) and a scripting language (where people want clarity, readability, maintainability by multiple people over longer times) is what gives rise to the short form / long form versions of everything.
gci -r | sls (date)
Get-ChildItem -Recurse | Select-String -Pattern (Get-Date)
Get-
cmdlets if the Get-
is left outFwiw, it appears to be this line in the source code of System.Management.Automation/engine/MergedCommandParameterMetadat.cs
, which someone on the PowerShell Slack identified, which actually does the parameter match:
foreach (string parameterName in _bindableParameters.Keys)
{
// ---
if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(parameterName, name, CompareOptions.IgnoreCase))
// ---
{
// If it is an exact match then only return the exact match
// as the result
if (tryExactMatching && String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase))
{
return _bindableParameters[parameterName];
}
else
{
matchingParameters.Add(_bindableParameters[parameterName]);
}
}
}
PowerShell allows using the initial characters of a parameter name as long as they are unambiguous.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With