я могу сделать один параметр обязательным на основе _value_ другого параметра? - PullRequest
3 голосов
/ 01 марта 2020

Если для параметра One установлено значение bbb, то я хочу сделать параметр два обязательным. Можно ли это как-то сделать с наборами параметров или мне просто нужно добавить эту логику c в сам скрипт?

Пример идеи о том, что мне нужно:

 param (
        [Parameter(Mandatory, ParameterSetName = 'default')]
        [ValidateSet(“aaa”, ”bbb”, ”ccc”, "ddd")]
        [String]
        $One,

        [Parameter(ParameterSetName = 'default')]
        [ValidateScript( { $One -eq 'bbb'; THEN MAKE THIS PARAM MANDATORY! })]
        [String]
        $Two
    )

Значение $ One, похоже, еще не установлено, так как я пытался это сделать, и one.txt пуст

[ValidateScript( { $One > One.txt; $true })]

Edit: в то время как есть DynamicParam {}, который выглядит, как если бы вы только начали, process, end, et c setup. Это простая функция, которую я не хочу добавлять к ней. Кроме того, для работы DynamicParam требуется необычное количество стандартного кода

Редактировать: Хорошо, похоже, что DynamicParam - единственный способ, но я считаю его безумным. Это странно и не читаемо, но я все же предпочел бы, чтобы powershell обрабатывал проверку для меня.

Делать это самому, хотя все еще довольно просто ...

if ($One -eq 'bbb' -and -not $Two) {
    ThrowError Param Two required when One set to $One
}

Ответы [ 2 ]

3 голосов
/ 01 марта 2020

Используйте значение по умолчанию для параметра -Two, чтобы принудительно применить требуемые логи c, с помощью оператора if, который использует Throw:

param (
  [Parameter(Mandatory, ParameterSetName = 'default')]
  [ValidateSet('aaa', 'bbb', 'ccc', 'ddd')]
  [String]
  $One,

  [Parameter(ParameterSetName = 'default')]
  [String]
  $Two = $(if ($One -eq 'bbb') { Throw "-Two must be passed if -One equals 'bbb'." })
)

"-One: $One; -Two: $Two"

Примечание: Эмуляция (условно) обязательного параметра с Throw означает, что поведение отличается от обычного Mandatory параметром в том, что последний запрашивает , когда значение равно не дано.

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

Приведенное выше решение основано на том факте, что значения по умолчанию оцениваются после того, как были связаны явно переданные аргументы.

Гораздо более многословной альтернативой является использование динамика c параметра , как показано в Ответ Васиф Хасана , полагается на то же время, хотя и имеет преимущество, демонстрируя нормальное поведение подсказки для пропущенного обязательного значения.

На момент написания статьи ответ Васифа не работал в том виде, в котором он был опубликован, Итак, вот рабочее решение; обратите внимание, что использование DynamicParam синтаксически требует (хотя бы одного) блоков begin, process и end .

# Syntax requires PSv5+:
using namespace System.Management.Automation

param( 
  [Parameter(Mandatory, ParameterSetName='default')]
  [ValidateSet('aaa', 'bbb', 'ccc', 'ddd')]
  [String]$One
)

# Define parameter -Two *dynamically*, so that its Mandatory property
# can be based on the specific value of the already-bound static -One parameter.
DynamicParam {

  # Create a the dictionary of dynamic parameters.
  $dict = [RuntimeDefinedParameterDictionary]::new()

  # Define and add the -Two parameter 
  $paramName = 'Two'
  $dict.Add(
    $paramName,
    [RuntimeDefinedParameter]::new(
      $paramName,
      [string],
      [ParameterAttribute] @{
        ParameterSetName = 'default'
        # *Conditionally* make the parameter mandatory, depending on the value
        # of the already-bound static -One parameter.
        Mandatory = $One -eq 'bbb'
      }
    )
  )

  # Return the dictionary
  return $dict
}

begin {

  # NOTE: Dynamic parameter values do not become local variables the way
  #       they do for static parameters; the value must be accessed via the
  #       automatic $PSBoundParameters dictionary.
  $Two = $PSBoundParameters['Two']

  "-One: $One; -Two: $Two"

}
0 голосов
/ 01 марта 2020

Вы ищете динамические c параметры: Условные параметры PowerShell

param( 
  [String]$One
)

DynamicParam {
  # Create a parameter dictionary
  $runtimeParams = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

  # Populate it with parameters, with optional attributes

  $attribs = New-Object  System.Collections.ObjectModel.Collection[System.Attribute]

  $mandatoryAttrib = New-Object System.Management.Automation.ParameterAttribute
  $mandatoryAttrib.Mandatory = ($one -eq "bbb")
  $attribs.Add($mandatoryAttrib)

  $param = New-Object System.Management.Automation.RuntimeDefinedParameter('Two', String, $attribs)
}
Begin {
  # If desired, move dynamic parameter values to variables
  $ParameterName = $PSBoundParameters['Two']
}

  # Do like regular

Без блока процесса он будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...