如何强制指定一组参数中的至少一个参数?

Jak*_*ake 5 powershell

我有一个 PowerShell 函数,它需要一个字符串和三个开关。所以调用会是这样的:

My-Function "some string" -Switch1 -Switch2 -Switch3
Run Code Online (Sandbox Code Playgroud)

但是,我想让此函数仅在提供了字符串和至少一个开关的情况下运行。所以:

My-Function "some string" -Switch1 -Switch3  # Valid
My-Function "some string" -Switch2           # Valid
My-Function "some string"                    # Invalid
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过检查是否已使用对象传递开关来实现这一点$MyInvocation,但是有没有办法使用ParameterParameterSet属性来做到这一点?

简而言之,这就是我正在尝试做的事情:

  • 每次调用该函数时都必须提供该字符串。
  • 每次调用该函数时都必须至少提供一个开关。

Ans*_*ers 4

我认为您不能使用参数集和强制参数来做到这一点。如果您使用交替的强制参数定义了 3 个不同的参数集,如下所示:

Param(
  [Parameter(Mandatory=$true)]
  [string]$Text,

  [Parameter(Mandatory=$true, ParameterSetName='o1')]
  [Parameter(Mandatory=$false, ParameterSetName='o2')]
  [Parameter(Mandatory=$false, ParameterSetName='o3')]
  [Switch][bool]$Switch1,

  [Parameter(Mandatory=$false, ParameterSetName='o1')]
  [Parameter(Mandatory=$true, ParameterSetName='o2')]
  [Parameter(Mandatory=$false, ParameterSetName='o3')]
  [Switch][bool]$Switch2,

  [Parameter(Mandatory=$false, ParameterSetName='o1')]
  [Parameter(Mandatory=$false, ParameterSetName='o2')]
  [Parameter(Mandatory=$true, ParameterSetName='o3')]
  [Switch][bool]$Switch3
)
Run Code Online (Sandbox Code Playgroud)

如果您只使用其中一个开关,它就可以工作:

My-Function "foo" -Switch2
Run Code Online (Sandbox Code Playgroud)

但如果您使用多个开关,则会失败:

Param(
  [Parameter(Mandatory=$true)]
  [string]$Text,

  [Parameter(Mandatory=$true, ParameterSetName='o1')]
  [Parameter(Mandatory=$false, ParameterSetName='o2')]
  [Parameter(Mandatory=$false, ParameterSetName='o3')]
  [Switch][bool]$Switch1,

  [Parameter(Mandatory=$false, ParameterSetName='o1')]
  [Parameter(Mandatory=$true, ParameterSetName='o2')]
  [Parameter(Mandatory=$false, ParameterSetName='o3')]
  [Switch][bool]$Switch2,

  [Parameter(Mandatory=$false, ParameterSetName='o1')]
  [Parameter(Mandatory=$false, ParameterSetName='o2')]
  [Parameter(Mandatory=$true, ParameterSetName='o3')]
  [Switch][bool]$Switch3
)
Run Code Online (Sandbox Code Playgroud)

我会使用经过设置验证的强制参数来代替:

Param(
  [Parameter(Mandatory=$true)]
  [string]$Text,

  [Parameter(Mandatory=$true)]
  [ValidateSet('Switch1', 'Switch2', 'Switch3', ignorecase=$true)]
  [string[]]$Options
)
Run Code Online (Sandbox Code Playgroud)

这将允许您像这样调用该函数:

My-Function "foo" -Options Switch1
My-Function "foo" -Options Switch2,Switch3
Run Code Online (Sandbox Code Playgroud)

或者您可以将所有三个开关设置为可选并在函数内验证它们:

Param(
  [Parameter(Mandatory=$true)]
  [string]$Text,

  [Parameter(Mandatory=$false)]
  [Switch][bool]$Switch1,

  [Parameter(Mandatory=$false)]
  [Switch][bool]$Switch2,

  [Parameter(Mandatory=$false)]
  [Switch][bool]$Switch3
)

if (-not ($Switch1.IsPresent -or $Switch2.IsPresent -or $Switch3.IsPresent)) {
  throw 'Missing switch'
}
Run Code Online (Sandbox Code Playgroud)

动态参数可能是另一种选择,但我不能肯定地说。