Consider this function:
function Test-Discrimination
{
[CmdletBinding()]
param
(
[parameter(ValueFromPipeline = $true,
Mandatory = $true,
ParameterSetName = 'string')]
[string]
$String,
[parameter(ValueFromPipeline = $true,
Mandatory = $true,
ParameterSetName = 'hashtable')]
[hashtable]
$Hashtable,
[parameter(ValueFromPipeline = $true,
Mandatory = $true,
ParameterSetName = 'pscustomobject')]
[pscustomobject]
$PsCustomObject
)
process
{
$PSCmdlet.ParameterSetName
}
}
Piping [pscustomobject] behaves as I expect:
PS C:\> New-Object pscustomobject | Test-Discrimination
pscustomobject
However, piping [string] throws an exception:
PS C:\> 'string' | Test-Discrimination
Test-Discrimination : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:12
+ 'string' | Test-Discrimination
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (string:String) [Test-Discrimination], Paramete
rBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Test-Discrimination
So does [hashtable]:
PS C:\> @{} | Test-Discrimination
Test-Discrimination : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:7
+ @{} | Test-Discrimination
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.Collections.Hashtable:Hashtable) [Test-
Discrimination], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Test-Discrimination
Adding DefaultParameterSetName='hastable' causes [hashtable] but not [string] to resolve correctly.
I'm not experienced at interpreting the output from Trace-Command. I did notice the output for [string] includes this line:
BIND arg [string] to param [PsCustomObject] SUCCESSFUL
Which seems like PowerShell is considering [string] to be a [PsCustomObject]. But 'string' -is [pscustomobject] evaluates to $false.
This all leaves me with the following questions:
- Why can't PowerShell select a parameter set based on the difference in type between a
[string]and a[pscustomobject]? - Is the reason is that PowerShell considers a
[string]to be a[pscustomobject]? If so, why would that be? - Is there a workaround that allows me to use different types to select different parameter sets?