【问题标题】:Powershell - Multiple parameters - ConditionsPowershell - 多个参数 - 条件
【发布时间】:2021-09-13 13:14:36
【问题描述】:

我想在 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。我不能决定是不是。谁能想出一个小例子来做到这一点?提前致谢。感谢您抽出宝贵时间帮助我。

【问题讨论】:

  • 好问题,但我不确定这是否基于意见。 Switch 更优雅,更易于阅读 imo。你也可以使用$PSBoundParameters
  • 除了Mathias's helpful answer之外,您还可以将switch与多个return语句一起使用。

标签: powershell switch-statement conditional-statements


【解决方案1】:

您正在寻找 $PSBoundParameters 自动变量 - 它是一个特殊的字典/哈希表,其中包含调用者传递给函数的参数值:

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
}

【讨论】:

  • 非常感谢马蒂亚斯。那是我第一次接触 PSBoundParameters。 :D 非常酷的功能。
【解决方案2】:

为了扩展 Mathias 的好答案,当您有多个条件时,我发现最简单的方法是使用保护子句。 保护子句是这些非常简单的小函数,它们返回真/假值。

如果你在你的if 块中把这些串起来,它的逻辑就非常非常容易理解。比重复检查来自PSBoundParameters 的值容易得多,恕我直言。

这是一个例子。


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

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

这些非常简单,您可能会看着它们并说“为什么还要麻烦”。原因如下!

一旦我们有了它们,我们就可以在父函数中调用它们,因为它们只返回真/假,它们正好适合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

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

【讨论】:

  • 我会强烈推荐$Object -is [int]代替$Object.GetType().Name -eq [Int].Name :-)
  • 好电话,我不知道 PowerShell 暴露了 -is 运算符!
猜你喜欢
  • 2012-05-31
  • 1970-01-01
  • 2012-10-27
  • 2021-12-25
  • 2013-04-14
  • 2015-07-24
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
相关资源
最近更新 更多