我可以在 PowerShell 中为参数指定条件默认值吗?
Can I specify conditional default values for a parameter in PowerShell?
我想如果这是可能的,它可能会使用参数集,所以我尝试了以下方法:
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
有没有更好的方法来完成这个?
以下应该有效:
因为不再需要显式参数集,所以我省略了它们;没有特定属性,也不再严格需要 [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 (or @(...)
, the array-subexpression operator) 将代码转换为表达式;这些案例是:
- 一个
Throw
语句(以及假设的 exit
和 return
语句,但您不会在此上下文中使用它们)
- 复合构造,例如
foreach
、while
、...
- 多个命令、表达式或复合结构,用
;
分隔
但是,始终使用$(...)
(或@(...)
)来封装计算默认值的代码是安全的,为简单起见,您可以选择这样做。
这些表达式在 显式指定的参数已绑定后计算,这允许表达式检查哪些参数已绑定,通过自动 $PSBoundParameters
变量:
('Value2', 'Value1')[$PSBoundParameters.ContainsKey('SomeOtherThing')]
只是
的更简洁的重新表述
if ($PSBoundParameters.ContainsKey('SomeOtherThing')) { 'Value1' } else { 'Value2' }
当用作数组索引(整数)时,它利用映射到 0
($false
)和 1
($true
)的 [bool]
值。
在 PowerShell v7+ 中,您可以改用 三元条件,它具有缩短求值的附加优势:
$PSBoundParameters.ContainsKey('SomeOtherThing') ? 'Value1' : 'Value2'
您可能需要查看动态参数。您声明一个名为 dynamicparams {} 的部分,您可以在其中动态创建参数。
我想如果这是可能的,它可能会使用参数集,所以我尝试了以下方法:
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
有没有更好的方法来完成这个?
以下应该有效:
因为不再需要显式参数集,所以我省略了它们;没有特定属性,也不再严格需要 [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 (or@(...)
, the array-subexpression operator) 将代码转换为表达式;这些案例是:- 一个
Throw
语句(以及假设的exit
和return
语句,但您不会在此上下文中使用它们) - 复合构造,例如
foreach
、while
、... - 多个命令、表达式或复合结构,用
;
分隔
- 一个
但是,始终使用
$(...)
(或@(...)
)来封装计算默认值的代码是安全的,为简单起见,您可以选择这样做。这些表达式在 显式指定的参数已绑定后计算,这允许表达式检查哪些参数已绑定,通过自动
$PSBoundParameters
变量:('Value2', 'Value1')[$PSBoundParameters.ContainsKey('SomeOtherThing')]
只是
的更简洁的重新表述if ($PSBoundParameters.ContainsKey('SomeOtherThing')) { 'Value1' } else { 'Value2' }
当用作数组索引(整数)时,它利用映射到0
($false
)和1
($true
)的[bool]
值。在 PowerShell v7+ 中,您可以改用 三元条件,它具有缩短求值的附加优势:
$PSBoundParameters.ContainsKey('SomeOtherThing') ? 'Value1' : 'Value2'
您可能需要查看动态参数。您声明一个名为 dynamicparams {} 的部分,您可以在其中动态创建参数。