首页 > 解决方案 > 我可以根据不同参数的 _value_ 强制一个参数吗?

问题描述

如果参数一设置为 bbb,那么我想强制参数二。是否有可能以某种方式使用参数集来做到这一点,或者我只需要将这个逻辑添加到脚本本身?

我需要的示例想法:

 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 })]

编辑

虽然只有当您设置了开始、处理、结束等设置时,才会出现 DynamicParam{}。这是一个简单的功能,我不想添加它。DynamicParam 似乎也需要大量的样板代码才能工作

编辑

看起来 DynamicParam 是唯一的方法,但我认为这很疯狂。这很奇怪且不可读,但我仍然更喜欢 Powershell 为我处理验证。

虽然自己做仍然很简单:

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

标签: functionpowershellparameters

解决方案


-Two通过使用以下语句的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参数不同,后者在未给出值时提示。

基于验证属性的解决方案会更可取,但验证属性不是为参数验证而设计的,并且不能保证其评估的特定顺序。

上述解决方案依赖于在绑定显式传递的参数 评估默认值的事实。

更详细的替代方法是使用 动态参数Wasif Hasan 的回答所示,依赖于相同的时间,尽管它确实具有表现出正常提示缺失强制值行为的优势。

在撰写本文时,Wasif 的答案并没有像发布的那样起作用,所以这是一个可行的解决方案;请注意语法上的使用如何DynamicParam需要(至少之一) the begin,processendblocks

# 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"

}

推荐阅读