【问题标题】:Can I specify conditional default values for a parameter in PowerShell?我可以为 PowerShell 中的参数指定条件默认值吗?
【发布时间】:2017-03-09 04:59:23
【问题描述】:

我想如果这可能的话,它可能会使用参数集,所以我尝试了以下方法:

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

执行这个来创建函数会导致错误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
}

可行但看起来很丑:

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

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

【问题讨论】:

    标签: powershell parameters default-value


    【解决方案1】:

    以下应该有效:

    既然不再需要显式参数集,我就省略了它们;如果没有特定属性,[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
    
    }
    
    • 可以使用表达式作为参数默认值。

      • 以上代码一个表达式,因此可以按原样使用。
      • 要将单个命令(对 PowerShell cmdlet、函数、脚本或外部程序的调用)用作表达式,请将其括在(...)grouping operator 中。李>
      • 在所有其他情况下,您需要$(...)subexpression operator(或@(...)array-subexpression operator)将代码转换为表达式;这些情况是:
        • Throw 语句(假设还有exitreturn 语句,但您不会在这种情况下使用它们)
        • 复合构造,例如foreachwhile、...
        • 多个命令、表达式或复合结构,用;分隔
    • 但是,总是使用$(...)(或@(...))来包含计算默认值的代码是安全的,为简单起见,您可以选择这样做。

    • 这些表达式在明确指定的参数被绑定后进行评估,这允许表达式通过自动$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'

    【讨论】:

    • 谢谢。用括号括起来的条件默认值是我想要的。
    • 很高兴听到这个消息,@SubjectiveReality;从那以后我意识到$(...) 通常是不需要的:表达式可以按原样使用,单个命令可以包含在(...) 中。但是,鉴于这些区别可能并不明显,因此可以选择使用$(...) - 请参阅我的更新。
    【解决方案2】:

    您可能想查看动态参数。您声明一个名为 dynamicparams {} 的部分,您可以在其中动态创建参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-26
      • 2011-06-02
      • 2016-04-10
      • 1970-01-01
      • 2023-03-16
      • 2016-06-10
      • 1970-01-01
      相关资源
      最近更新 更多