Powershell - 多个参数 - 条件

Powershell - Multiple parameters - Conditions

我想在 powershell 中创建一个脚本,它根据设置或未设置的参数做几件事。我的代码如下所示:

Param(
    [parameter(Mandatory=$true,Position=1)]
    [String]$var1 ,
    [parameter(Mandatory=$false,Position=2)]
    [int]$var2 ,
    [parameter(Mandatory=$false,Position=3)]
    [int]$var3 ,
    [parameter(Mandatory=$false,Position=4)]
    [string]$var4
)
.... 

然后我想做一个 if-elseif 来检查设置了哪些参数:

if (!$var2 -and !$var3 -and !$var4) {
  ... Do something with $var1 
} elseif (!$var2 -and !$var3 -and $var4) {
 ... Do something with $var1 and $var4
} else {
 throw an error
}

.. 或者如果更合适的话做一个 switch case。我不能决定是不是。谁能想出一个小例子来做到这一点?提前致谢。也感谢您花时间帮助我。

您正在查找 $PSBoundParameters 自动变量 - 它是一个特殊的 dictionary/hashtable,包含调用者传递给函数的参数值:

if(!$PSBoundParameters.ContainsKey('var2') -and !$PSBoundParameters.ContainsKey('var3') -and !$PSBoundParameters.ContainsKey('var4')){
    # only $var1 has an argument value
}

$PSBoundParameters 作为哈希表的好处在于,如果你想将可选参数传递给另一个函数,你可以 splat it:

function Write-CustomHost {
  param(
    [Parameter(Mandatory = $true)]
    $Object,

    [Parameter(Mandatory = $false)]
    [ValidateSet('Red','Green')]
    [string]$ForegroundColor
  )

  Write-Host @PSBoundParameters
}

为了扩展 Mathias 的出色答案,当您有多个条件时,我发现最简单的方法是使用保护子句。 保护子句 是这些非常简单的小函数,return 一个 true/false 值。

如果您将这些内容串在 if 块中,逻辑将非常非常容易理解。比反复检查来自 PSBoundParameters 的值容易得多,恕我直言。

这是一个例子。


function isRed {
    param([string]$ForegroundColor)
    $ForegroundColor -eq 'Red'
}

function isInt {
    param($object)
    $object -is [int]
}

这些非常简单,您可能会看着它们说 'why even bother'。原因如下!

一旦我们有了它们,我们就可以在父函数中调用它们,因为这些只是 return true/false,它们正好符合 if 条件,像这样:

#updating Mathias to add calling the guard clauses
function Write-CustomHost {
  param(
    [Parameter(Mandatory = $true)]
    $Object,

    [Parameter(Mandatory = $false)]
    [ValidateSet('Red','Green')]
    [string]$ForegroundColor
  )

  Write-Host @PSBoundParameters
  
  if (isRed $ForegroundColor -and isInt $Object){
    "this is a red Int, so lets do special handling here"
  }
}

Write-CustomHost -Object 1 -ForegroundColor Red

您可以通过实施简单的保护子句来实现代码的高级复杂性并保持易读性。你团队中的其他人或未来你会感谢你自己这样做的!