I have a function with four parameters, two of which can either be set or not. I'm trying to use Parameter Sets to identify which parameters have been set, but I'm hitting some issues with Parameter Set resolution. These are the four possible Parameter Sets -
When I test all four Parameter Sets using the example code below, the tests for Only an error object and Only some Splunk data both fail with the following error -
Test-ParameterSets : Parameter set cannot be resolved using the specified named parameters.
From my research it seems that this fails because PowerSehll can't work out whether the Parameter Set should be BothErrorObjectAndSplunkData
or OnlyErrorObject
/OnlySplunkData
, which I can understand.
How can I alter my code to determine which of above Parameter Sets are in use? If it's simply not possible with Parameter Sets, how else can I achieve my goal?
function Test-ParameterSets
{
[CmdLetBinding(DefaultParameterSetName="NeitherErrorObjectOrSplunkData")]
param(
[Parameter(Mandatory=$true)]
[Parameter(ParameterSetName="NeitherErrorObjectOrSplunkData")]
[Parameter(ParameterSetName="BothErrorObjectAndSplunkData")]
[parameter(ParameterSetName="OnlyErrorObject")]
[Parameter(ParameterSetName="OnlySplunkData")]
[String]$Message,
[parameter(ValueFromPipeline=$true)]
[Parameter(ParameterSetName="BothErrorObjectAndSplunkData")]
[parameter(ParameterSetName="OnlyErrorObject")]
[Object]$ErrorObject,
[Parameter(ParameterSetName="BothErrorObjectAndSplunkData")]
[Parameter(ParameterSetName="OnlySplunkData")]
[String[]]$SplunkData,
[ValidateSet("ERROR", "WARN", "INFO")]
[String]$Severity = "ERROR"
)
Write-Host "$message -"
Write-Host "-- Parameter Set: $($PSCmdlet.ParameterSetName)`n"
return
}
Test-ParameterSets -Message "Neither an error object or an Splunk data"
Test-ParameterSets -Message "Only an error object" -ErrorObject (New-Object -TypeName PSCustomObject)
Test-ParameterSets -Message "Only some Splunk data" -SplunkData "Test"
Test-ParameterSets -Message "Both an error object and Splunk data" -ErrorObject (New-Object -TypeName PSCustomObject) -SplunkData "Test"
Example code output
Neither an error object or an Splunk data -
-- Parameter Set: NeitherErrorObjectOrSplunkDataTest-ParameterSets : Parameter set cannot be resolved using the specified named parameters.
At line:31 char:1
+ Test-ParameterSets -Message "Only an error object" -ErrorObject (New- ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Test-ParameterSets], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Test-ParameterSetsTest-ParameterSets : Parameter set cannot be resolved using the specified named parameters.
At line:32 char:1
+ Test-ParameterSets -Message "Only some Splunk data" -SplunkData "Test ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Test-ParameterSets], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Test-ParameterSetsBoth an error object and Splunk data -
-- Parameter Set: BothErrorObjectAndSplunkData
Specify that the $ErrorObject
and $SplunkData
variables are mandatory for these sets.
This will allow PowerShell to distinguish between the sets if only one is provided, or both.
edited following David Gard's comments
function Test-ParameterSets
{
[CmdLetBinding(DefaultParameterSetName="NeitherErrorObjectOrSplunkData")]
param(
# edit: removed ParameterSetName as belong to all sets so redundant
[Parameter(Mandatory=$true)]
[String]$Message,
# edit: included ValueFromPipeline in the same Parameter declarations
# as ParameterSetName
[Parameter(ValueFromPipeline=$true, Mandatory=$true, ParameterSetName="BothErrorObjectAndSplunkData")]
[parameter(ValueFromPipeline=$true, Mandatory=$true, ParameterSetName="OnlyErrorObject")]
[Object]$ErrorObject,
[Parameter(Mandatory=$true, ParameterSetName="BothErrorObjectAndSplunkData")]
[Parameter(Mandatory=$true, ParameterSetName="OnlySplunkData")]
[String[]]$SplunkData,
[ValidateSet("ERROR", "WARN", "INFO")]
[String]$Severity = "ERROR"
)
Write-Host "$message -"
Write-Host "-- Parameter Set: $($PSCmdlet.ParameterSetName)`n"
return
}
Test-ParameterSets -Message "Neither an error object or an Splunk data"
Test-ParameterSets -Message "Only an error object" -ErrorObject (New-Object -TypeName PSCustomObject)
Test-ParameterSets -Message "Only some Splunk data" -SplunkData "Test"
Test-ParameterSets -Message "Both an error object and Splunk data" -ErrorObject (New-Object -TypeName PSCustomObject) -SplunkData "Test"
Output
Neither an error object or an Splunk data -
-- Parameter Set: NeitherErrorObjectOrSplunkData
Only an error object -
-- Parameter Set: OnlyErrorObject
Only some Splunk data -
-- Parameter Set: OnlySplunkData
Both an error object and Splunk data -
-- Parameter Set: BothErrorObjectAndSplunkData