Может передавать сценарию powershell один из двух аргументов, но не оба аргумента одновременно

#powershell #parameters #scripting #parameter-passing #optional-parameters

#powershell #параметры #сценарии #передача параметров #необязательно-параметры

Вопрос:

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

 Parameter set cannot be resolved using the specified named parameters.
  

Там также есть лакомый кусочек о неоднозначном параметре.

Раздел параметров моего скрипта выглядит следующим образом:

 [CmdletBinding(DefaultParameterSetName="None")]
param(
    [Parameter(Mandatory=$False, ParameterSetName="BuildExclude")]
    [ValidateSet('proj1','proj2', 'proj3', 'proj4')]
    [string[]]$BuildExclude,
    [Parameter(Mandatory=$False, ParameterSetName="SkipDbRestore")]
    [switch]$SkipDbRestore
)
  

Эти обычаи работают:

 .RunScript.ps1 -BuildExclude proj1, proj2
.RunScript.ps1 -SkipDbRestore
.RunScript.ps1 
  

Это использование не работает по вышеупомянутой причине:

 .RunScript.ps1 -BuildExclude proj1, proj2 -SkipDbRestore
  

Это не сработает, даже если я изменю порядок аргументов. Я попытался добавить позиции параметров, сделав BuildExclude=0 и SkipDbRestore=1 в надежде, что я смогу заставить их работать вместе, если я хотя бы сохраню их в таком порядке. Но это дает мне ту же ошибку двусмысленности. Чего мне не хватает? В идеале я хотел бы иметь возможность вызывать скрипт с параметрами в любом порядке и заставлять его выполнять правильные действия.

Ответ №1:

Наборы параметров очень похожи на перегруженные функции — вы используете их, чтобы указать, какие параметры вам требуются. В вашем исходном примере было два набора параметров, по одному параметру в каждом. Это вынуждает пользователя выбрать один из них. В другой ситуации у вас может быть функция, которая либо принимает параметр param1, ЛИБО param2 И param3. Вы бы выразили это как таковое:

 function Doit
{
    Param(
        [Parameter(Mandatory=$true, ParameterSetName="paramset1")]
        $param1,
        [Parameter(Mandatory=$true, ParameterSetName="paramset2")]
        $param2,
        [Parameter(Mandatory=$true, ParameterSetName="paramset2")]
        $param3
    )

    #code
}
  

Наборы параметров в сочетании с обязательными true / false дают огромный контроль над тем, как параметры передаются в вашу функцию.

В вашем примере вам просто не нужно указывать набор параметров, поскольку у вас есть только один. Таким образом, заголовок param вашей функции может быть указан следующим образом:

 function doit2
{
    param(
    [ValidateSet('proj1','proj2', 'proj3', 'proj4')]
    [string[]]$BuildExclude,
    [switch]$SkipDbRestore
    )
}