Mike's PowerShell Musings

Menu

PowerShell Parameter Disambiguation and a Surprise

When you’re learning PowerShell one of the first things you will notice is that you don’t have to use the full parameter name. This is because of something called parameter disambiguation.

When it works

For instance, instead of saying Get-ChildItem -Recurse, you can say Get-ChildItem -R. Get-ChildItem only has one (non-dynamic) parameter that started with the letter ‘R’.. Since only one parameter matches, PowerShell figures you must mean that one. As a side note, dynamic parameters like -ReadOnly are created at run-time and are treated a bit differently.

Here’s the error message. Notice that it included a couple of other parameters as possibilities:

AmbiguousParameter error

When it doesn’t work

This doesn’t always work, though. An easy example is with Get-Service. You can’t say Get-Service -In because you haven’t specified enough of the parameter name for PowerShell to work out what parameter you meant. With Get-Service, both -Include and -InputObject start with -In, so PowerShell can’t tell which of these you meant.

Trying it ourselves

Let’s write a quick function to make sure we understand what’s going on.

function test-param{
Param($da,$de)
$true
}

Calling this function with test-param -d gives us the same kind of error as before:

Interestingly (this is the surprise) if we make this an advanced function (and we should almost always do that), something strange happens.

function test-param{
[CmdletBinding()]
Param($da,$de)
$true
}

Remember that one of the benefits of having an advanced function is that it now supports common parameters (like -debug).

When we call it with test-param -de, however, we don’t get an ambiguous parameter message! It’s asking for a value for -de!

So, even though we got a couple of common parameters in the error message for Get-Service -In, the -Debug common parameter isn’t considered in the disambiguation for this function.