How can a function tell if a parameter was passed in as an alias, or an object in the pipeline's property was matched as an alias? How can it get the original name?
Suppose my Powershell cmdlet accepts pipeline input and I want to use ValueFromPipelineByPropertyName. I have an alias set up because I might be getting a few different types of objects, and I want to be able to do something slightly different depending on what I receive.
This does not work
function Test-DogOrCitizenOrComputer
{
[CmdletBinding()]
Param
(
# Way Overloaded Example
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[Alias("Country", "Manufacturer")]
[string]$DogBreed,
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[string]$Name
)
# For debugging purposes, since the debugger clobbers stuff
$foo = $MyInvocation
$bar = $PSBoundParameters
# This always matches.
if ($MyInvocation.BoundParameters.ContainsKey('DogBreed')) {
"Greetings, $Name, you are a good dog, you cute little $DogBreed"
}
# These never do.
if ($MyInvocation.BoundParameters.ContainsKey('Country')) {
"Greetings, $Name, proud citizen of $Country"
}
if ($MyInvocation.BoundParameters.ContainsKey('Manufacturer')) {
"Greetings, $Name, future ruler of earth, created by $Manufacturer"
}
}
Executing it, we see problems
At first, it seems to work:
PS> Test-DogOrCitizenOrComputer -Name Keith -DogBreed Basset
Greetings, Keith, you are a good dog, you cute little Basset
The problem is apparent when we try an Alias
:
PS> Test-DogOrCitizenOrComputer -Name Calculon -Manufacturer HP
Greetings, Calculon, you are a good dog, you cute little HP
Bonus fail, doesn't work via pipeline:
PS> New-Object PSObject -Property @{'Name'='Fred'; 'Country'='USA'} | Test-DogOrCitizenOrComputer
Greetings, Fred, you are a good dog, you cute little USA
PS> New-Object PSObject -Property @{'Name'='HAL'; 'Manufacturer'='IBM'} | Test-DogOrCitizenOrComputer
Greetings, HAL, you are a good dog, you cute little IBM
Both $MyInvocation.BoundParameters and $PSBoundParameters contain the defined parameter names, not any aliases that were matched. I don't see a way to get the real names of arguments matched via alias.
It seems PowerShell is not only being 'helpful' to the user by silently massaging arguments to the right parameters via aliases, but it's also being 'helpful' to the programmer by folding all aliased inputs into the main parameter name. That's fine, but I can't figure out how to determine the actual original parameter passed to the Cmdlet (or the object property passed in via pipeline)
How can a function tell if a parameter was passed in as an alias, or an object in the pipeline's property was matched as an alias? How can it get the original name?