我可以在 PowerShell 中为参数指定条件默认值吗?

Chr*_*son 4 parameters powershell default-value

我想如果这是可能的,它可能会使用参数集工作,所以我尝试了以下操作:

Function New-TestMultipleDefaultValues {
    [CmdletBinding(DefaultParameterSetName="Default1")]
    param (
        [Parameter(Mandatory,ParameterSetName="Default1")]$SomeOtherThingThatIfSpecifiedShouldResultInTest1HavingValue1,
        [Parameter(ParameterSetName="Default1")]$Test1 = "Value1",
        [Parameter(ParameterSetName="Default2")]$Test1 = "Value2"
    )
    $PSBoundParameters
}
Run Code Online (Sandbox Code Playgroud)

执行此操作以创建函数会导致错误,Duplicate parameter $test1 in parameter list.因此这种方式看起来不是一种选择。

在这一点上,我唯一能想到的就是做这样的事情:

Function New-TestMultipleDefaultValues {
    param (
        $SomeOtherThingThatIfSpecifiedShouldResultInTest1HavingValue1,
        $Test1
    )
    if (-not $Test1 -and $SomeOtherThingThatIfSpecifiedShouldResultInTest1HavingValue1) {
        $Test1 = "Value1"
    } elseif (-not $Test1 -and -not $SomeOtherThingThatIfSpecifiedShouldResultInTest1HavingValue1) {
        $Test1 = "Value2"
    }

    $Test1
}
Run Code Online (Sandbox Code Playgroud)

哪个有效但看起来很丑:

PS C:\Users\user> New-TestMultipleDefaultValues -SomeOtherThingThatIfSpecifiedShouldResultInTest1HavingValue1 "thing"
Value1
PS C:\Users\user> New-TestMultipleDefaultValues
Value2
PS C:\Users\user> New-TestMultipleDefaultValues -Test1 "test"
test
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来实现这一点?

mkl*_*nt0 5

以下应该工作:

由于不再需要显式参数集,因此我省略了它们;如果没有特定的属性,[Parameter()]也不再严格需要这些属性。

Function New-TestMultipleDefaultValues {

  [CmdletBinding()]
  param (
    [Parameter()] $SomeOtherThing,
    [Parameter()] $Test1 = 
      ('Value2', 'Value1')[$PSBoundParameters.ContainsKey('SomeOtherThing')]
  )
    
  # * As expected, if -Test1 <value> is explicitly specified, 
  #   parameter variable $Test1 receives that value.
  # * If -Test1 is omitted, the expression assigns 'Value1` to $Test1
  #   if -SomeOtherThing was specified, and 'Value2' otherwise.
  $Test1 # Output the effective value of $Test1

}
Run Code Online (Sandbox Code Playgroud)
  • 可以使用表达式作为参数默认值。

    • 上面的代码一个表达式,因此可以按原样使用。
    • 使用单个命令(到一个PowerShell cmdlet,函数,脚本或外部程序的调用)作为表达,它括在(...)中,分组操作
    • 在需要所有其他情况下$(...),该子表达式算子(或@(...),所述阵列子表达式运算符)到代码转换为一个表达式; 这些情况是:
      • 一个Throw陈述(并且,假设,exitreturn陈述,但你不会在这种情况下使用它们)
      • 复合结构,例如foreach, while, ...
      • 多个命令、表达式或复合结构,用;
  • 但是,始终使用$(...)(或@(...)) 来包含计算默认值的代码是安全的,为了简单起见,您可以选择这样做。

  • 这些表达式在明确指定的参数被绑定后被评估,这允许表达式通过自动$PSBoundParameters变量检查哪些参数被绑定:

    • ('Value2', 'Value1')[$PSBoundParameters.ContainsKey('SomeOtherThing')]只是一个更简洁的重新表述,当用作数组索引(整数)时
      if ($PSBoundParameters.ContainsKey('SomeOtherThing')) { 'Value1' } else { 'Value2' }
      ,它利用了[bool]映射到0( $false) 和1( $true)上的值。

    • 在 PowerShell v7+ 中,您可以改用三元条件,它具有短路评估的额外优势: $PSBoundParameters.ContainsKey('SomeOtherThing') ? 'Value1' : 'Value2'