PowerShell не может определить, какой набор параметров используется

У меня есть функция с четырьмя параметрами, два из которых можно установить или нет. Я пытаюсь использовать наборы параметров, чтобы определить, какие параметры были установлены, но у меня возникают некоторые проблемы с разрешением набора параметров. Это четыре возможных набора параметров -

  • NeitherErrorObjectOrSplunkData
  • BothErrorObjectAndSplunkData
  • OnlyErrorObject
  • OnlySplunkData

Когда я тестирую все четыре набора параметров, используя приведенный ниже пример кода, тесты для Только объект ошибки и Только некоторые данные Splunk не работают со следующей ошибкой:

Test-ParameterSets: набор параметров не может быть разрешен с использованием указанных именованных параметров.

Из моих исследований кажется, что это не удается, потому что PowerSehll не может определить, должен ли набор параметров быть BothErrorObjectAndSplunkData или _2 _ / _ 3_, что я могу понять.

Как я могу изменить свой код, чтобы определить, какие из вышеперечисленных наборов параметров используются? Если это просто невозможно с наборами параметров, как еще я могу достичь своей цели?


Пример кода

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"

Пример вывода кода

Ни объект ошибки, ни данные Splunk -
- Набор параметров: NeitherErrorObjectOrSplunkData

Test-ParameterSets: набор параметров не может быть разрешен с использованием указанных именованных параметров.
В строке: 31 символ: 1
+ Test-ParameterSets -Message "Только объект ошибки" -ErrorObject (New- ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: InvalidArgument: (:) [Test-ParameterSets], ParameterBindingException
+ FullyQualifiedErrorId: AmbiguousParameterSet, Test-ParameterSets

Test-ParameterSets: набор параметров не может быть разрешен с использованием указанных именованных параметров.
В строке: 32 символа: 1
+ Test-ParameterSets -Message "Только некоторые данные Splunk" -SplunkData "Test ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: InvalidArgument: (:) [Test-ParameterSets], ParameterBindingException
+ FullyQualifiedErrorId: AmbiguousParameterSet, Test-ParameterSets

И объект ошибки, и данные Splunk -
- Набор параметров: BothErrorObjectAndSplunkData


person David Gard    schedule 19.07.2017    source источник


Ответы (1)


Укажите, что переменные $ErrorObject и $SplunkData являются обязательными для этих наборов.

Это позволит PowerShell различать наборы, если предоставляется только один или оба.

отредактировал после комментариев Дэвида Гарда

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"

Вывод

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
person G42    schedule 19.07.2017
comment
Я вижу, что могу удалить все объявления набора параметров из параметра $Message, и он по-прежнему работает - намного чище. - person David Gard; 19.07.2017
comment
Ах, и я только что обнаружил, что это означает, что ValueFromPipeline=$true также должен находиться в том же Parameter объявлении, что и Mandatory и ParameterSetName. - person David Gard; 19.07.2017
comment
@DavidGard Рад слышать, что все разобрано. Рег удаление объявления набора параметров: это правда; когда наборы параметров не указаны, параметр можно использовать в любом наборе. Не знал, что в случае с ValueFromPipeLine; это имеет смысл, поскольку это возможно $true для одного набора и $false для другого. Моя общая практика - включать все соответствующие аргументы в одно и то же объявление Parameter. - person G42; 19.07.2017
comment
Да, имеет смысл включать все - лучше быть явным. Спасибо за обновление ответа. - person David Gard; 19.07.2017