Как установить зависимости параметров

До сих пор я более или менее избегал наборов параметров в моем сценарии PowerShell, так как считаю их очень подробными и довольно сложными для реализации для сложных зависимостей.
В Stackru есть несколько похожих вопросов и ответов, но я могу найти приемлемое решение или обходной путь для моей ситуации. Фактический сценарий еще более сложен, но вот где я застрял:

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1Switch')]
        [Parameter(ParameterSetName = 'Param2Switch')]
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1Switch')]
        [Parameter(ParameterSetName = 'Param2Switch')]
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

Правила параметра:

  • Хотя бы один Param# (Param1, Param2 или Param3) параметр должен быть предоставлен
  • Только один Param# (Param1, Param2 или Param3) параметр может быть предоставлен
  • Переключатели (Switch1 а также Switch2) являются необязательными, могут поставляться (один или оба) только с Param1 или Param2 параметр

Это означает, что следующие команды должны вызвать ошибку:

Test-ParamSet
Test-ParamSet -Param3 'Test' -Switch1

И следует принять следующие команды:

Test-ParamSet -Param1 'Test'
Test-ParamSet -Param1 'Test' -Switch1
Test-ParamSet -Param2 'Test' -Switch1 -Switch2

Проблема связана со следующей командой:

Test-ParamSet -Param2 'Test'

Выдает непредвиденную ошибку:

Test-ParamSet : Parameter set cannot be resolved using the specified named parameters. 
One or more parameters issued cannot be used together or an insufficient number of parameters were provided.
At line:1 char:1
+ Test-ParamSet -Param2 'Test'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Test-ParamSet], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Test-ParamSet

Я предполагаю, что это связано с этой проблемой github, упомянутой mklement0 в mklement0 Как изменить сообщение выброса параметра?.

Но как я могу решить эту проблему или обойти ее с помощью наборов параметров?

2 ответа

Решение

Параметры переключателя должны входить в набор имен Param1 и Param2. Затем набор имен Param1Switch и Param2Switch можно удалить из$Param1 & $Param2 определение.

Вот и конечный результат.

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

Добавить в комментарии @SagePourpre и @iRon и добавить дополнительную информацию, которая может иметь отношение к делу.

В этом случае ошибка верна, и проблема в том, что вы одновременно сопоставляете 2 набора параметров -> без заданного набора параметров по умолчанию.

например, тест первого набора параметров:

Test-ParamSet -Param1 'Test'

Они соответствуют обоим наборам параметровParam1 а также Param1Switch. Он соответствует другому набору параметров, потому что два других переключателя являются необязательными. Но, поскольку вы указываетеDefaultParameterSetName='Param1' тогда Param1 по умолчанию выигрывает.

Во втором тесте набора параметров:

Test-ParamSet -Param2 'Test'

Опять же, они соответствуют обоим наборам параметровParam2 а также Param2Switch. Но поскольку нет набора параметров по умолчанию, указанного для "преодоления" разногласий, а переключатели являются необязательными (для соответствия второму набору параметров), это вызывает ошибку.

Решение состоит в том, чтобы упростить имена наборов, чтобы они могли соответствовать только одному набору за раз. Особенно если вы имеете дело с необязательными параметрами:

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1')]
        [Parameter(ParameterSetName = 'Param2')]
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

Другой способ сделать это - указать переключатели как обязательные для принудительного присвоения имени набора параметров определенному. например:

Function Test-ParamSet {
    [CmdletBinding(DefaultParameterSetName='Param1')][OutputType([Object[]])]Param (

        [Parameter(ParameterSetName = 'Param1', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        $Param1,

        [Parameter(ParameterSetName = 'Param2', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        $Param2,

        [Parameter(ParameterSetName = 'Param3', Mandatory = $True)]
        $Param3,

        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1And2Switch', Mandatory = $True)]     
        [Switch]$Switch1,

        [Parameter(ParameterSetName = 'Param1Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param2Switch', Mandatory = $True)]
        [Parameter(ParameterSetName = 'Param1And2Switch', Mandatory = $True)]     
        [Switch]$Switch2
    )
    Write-Host $PsCmdlet.ParameterSetName
}

Таким образом, у вас есть только одна опция ParameterSet для всех возможных решений и вы можете обрабатывать особые случаи с помощью переключателей.

Другие вопросы по тегам