如何在函数中指定 param() 部分,以便我可以使用 "F -opt val" 或 "F val_1 val_2" 调用函数?
How do I specifiy the param() section in a function so that I can call the function with either "F -opt val" or "F val_1 val_2"?
我正在尝试编写一个 PowerShell 函数,我可以使用开关调用并传递 one 值或不使用开关并传递 two 值:
option-or-value -opt one
option-or-value two three
我假设我需要参数集并且需要定义函数的 param()
部分如下:
function option-or-value {
param (
[parameter (
parameterSetName = 'using_option',
mandatory = $true
)][switch ] $opt,
[parameter (
parameterSetName = 'using_value',
mandatory = $true
)][string ] $val_0,
[parameter (
mandatory = $true
)][string ] $val_1
)
if ($using_option) {
$val_0 = '...'
}
write-host "val_0 = $val_0, val_1 = $val_1"
}
但是,我做错了什么,当我尝试调用该函数时,出现错误 无法找到接受参数的位置参数。
这让我感到惊讶,因为我认为参数集的全部意义在于函数可以区分不同的参数协议。
那么,我的假设哪里错了,如何实现这样的功能呢?
忘掉开关,创建第三个 [string]
参数并声明它是必需的,同时声明它自己的非默认参数集的一部分:
function Test-Option
{
[CmdletBinding(DefaultParameterSetName = 'UsingValue')]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'UsingValue', Position = 0)]
[string]$FirstValue,
[Parameter(Mandatory = $true, ParameterSetName = 'UsingValue', Position = 1)]
[string]$SecondValue = '...',
[Parameter(Mandatory = $true, ParameterSetName = 'UsingOption')]
[string]$Option
)
if($PSCmdlet.ParameterSetName -eq 'UsingOption'){
$FirstValue = $Option
}
Write-Host "First: $FirstValue, Second: $SecondValue"
}
为您提供所需的行为:
PS ~> Test-Option 123 456
First: 123, Second: 456
PS ~> Test-Option -Option 123
First: 123, Second: ...
PS ~> Test-Option -Option 123 456
Test-Optional : A positional parameter cannot be found that accepts argument '456'.
At line:1 char:1
+ Test-Option -Option 123 456
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Test-Option], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Test-Option
我同意 Mathias 的观点,即使用多个参数集比在此处使用开关更好。他的答案是正确的,但我认为稍微误解了您的问题,您的补充评论使您的问题变得更加清晰。
您想提供一个开关和一个值,还是不提供一个开关并被迫输入两个值?并且您希望有多个开关来确定该功能的实际作用。就这一点而言,我不同意,因为通常应该编写函数来做一件事并且把它做好。如果你有多项工作需要完成,那么你应该有不同的功能。
无论如何,我认为我建议只使用一个参数来指定 switch/action,而不是多个开关。您可以使用 ValidateSet()
来限制输入并提供自动完成功能。给代码!
function Test-OptionOrValue {
[CmdletBinding(DefaultParameterSetName = 'Non-Option')]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'Options')]
[ValidateSet( 'DoThis', 'DoThat', 'Other')]
$Action,
[Parameter(Mandatory = $true, ParameterSetName = 'Options')]
[Parameter(Mandatory = $true, ParameterSetName = 'Non-Option')]
[string]
$FirstValue,
[Parameter(Mandatory = $true, ParameterSetName = 'Non-Option')]
[string]
$SecondValue
)
if ($PSCmdlet.ParameterSetName -eq 'Non-Option') {
Write-Host "Both FirstValue and SecondValue required"
Write-Host "FirstValue: $FirstValue"
Write-Host "SecondValue: $SecondValue"
} elseif ($PSCmdlet.ParameterSetName -eq 'Options') {
Write-Host "Action argument provided: $Action"
Write-Host "Only FirstValue required"
Write-Host "FirstValue: $FirstValue"
Write-Host "SecondValue: $SecondValue"
switch ($action) {
'DoThis' { Write-Host "Performing 'DoThis' Action using FirstValue [$firstValue]" }
'DoThat' { Write-Host "Performing 'DoThat' Action using FirstValue [$firstValue]" }
'Other' { Write-Host "Performing 'Other' Action using FirstValue [$firstValue]" }
Default {}
}
}
}
使用示例
PS > Test-OptionOrValue -Action DoThis -FirstValue 32
Action argument provided: DoThis
Only FirstValue required
FirstValue: 32
SecondValue:
Performing 'DoThis' Action using FirstValue [32]
PS > Test-OptionOrValue -Action DoThat -FirstValue 32
Action argument provided: DoThat
Only FirstValue required
FirstValue: 32
SecondValue:
Performing 'DoThat' Action using FirstValue [32]
PS > Test-OptionOrValue -FirstValue 12 -SecondValue 23
Both FirstValue and SecondValue required
FirstValue: 12
SecondValue: 23
我正在尝试编写一个 PowerShell 函数,我可以使用开关调用并传递 one 值或不使用开关并传递 two 值:
option-or-value -opt one
option-or-value two three
我假设我需要参数集并且需要定义函数的 param()
部分如下:
function option-or-value {
param (
[parameter (
parameterSetName = 'using_option',
mandatory = $true
)][switch ] $opt,
[parameter (
parameterSetName = 'using_value',
mandatory = $true
)][string ] $val_0,
[parameter (
mandatory = $true
)][string ] $val_1
)
if ($using_option) {
$val_0 = '...'
}
write-host "val_0 = $val_0, val_1 = $val_1"
}
但是,我做错了什么,当我尝试调用该函数时,出现错误 无法找到接受参数的位置参数。
这让我感到惊讶,因为我认为参数集的全部意义在于函数可以区分不同的参数协议。
那么,我的假设哪里错了,如何实现这样的功能呢?
忘掉开关,创建第三个 [string]
参数并声明它是必需的,同时声明它自己的非默认参数集的一部分:
function Test-Option
{
[CmdletBinding(DefaultParameterSetName = 'UsingValue')]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'UsingValue', Position = 0)]
[string]$FirstValue,
[Parameter(Mandatory = $true, ParameterSetName = 'UsingValue', Position = 1)]
[string]$SecondValue = '...',
[Parameter(Mandatory = $true, ParameterSetName = 'UsingOption')]
[string]$Option
)
if($PSCmdlet.ParameterSetName -eq 'UsingOption'){
$FirstValue = $Option
}
Write-Host "First: $FirstValue, Second: $SecondValue"
}
为您提供所需的行为:
PS ~> Test-Option 123 456
First: 123, Second: 456
PS ~> Test-Option -Option 123
First: 123, Second: ...
PS ~> Test-Option -Option 123 456
Test-Optional : A positional parameter cannot be found that accepts argument '456'.
At line:1 char:1
+ Test-Option -Option 123 456
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Test-Option], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Test-Option
我同意 Mathias 的观点,即使用多个参数集比在此处使用开关更好。他的答案是正确的,但我认为稍微误解了您的问题,您的补充评论使您的问题变得更加清晰。
您想提供一个开关和一个值,还是不提供一个开关并被迫输入两个值?并且您希望有多个开关来确定该功能的实际作用。就这一点而言,我不同意,因为通常应该编写函数来做一件事并且把它做好。如果你有多项工作需要完成,那么你应该有不同的功能。
无论如何,我认为我建议只使用一个参数来指定 switch/action,而不是多个开关。您可以使用 ValidateSet()
来限制输入并提供自动完成功能。给代码!
function Test-OptionOrValue {
[CmdletBinding(DefaultParameterSetName = 'Non-Option')]
param (
[Parameter(Mandatory = $true, ParameterSetName = 'Options')]
[ValidateSet( 'DoThis', 'DoThat', 'Other')]
$Action,
[Parameter(Mandatory = $true, ParameterSetName = 'Options')]
[Parameter(Mandatory = $true, ParameterSetName = 'Non-Option')]
[string]
$FirstValue,
[Parameter(Mandatory = $true, ParameterSetName = 'Non-Option')]
[string]
$SecondValue
)
if ($PSCmdlet.ParameterSetName -eq 'Non-Option') {
Write-Host "Both FirstValue and SecondValue required"
Write-Host "FirstValue: $FirstValue"
Write-Host "SecondValue: $SecondValue"
} elseif ($PSCmdlet.ParameterSetName -eq 'Options') {
Write-Host "Action argument provided: $Action"
Write-Host "Only FirstValue required"
Write-Host "FirstValue: $FirstValue"
Write-Host "SecondValue: $SecondValue"
switch ($action) {
'DoThis' { Write-Host "Performing 'DoThis' Action using FirstValue [$firstValue]" }
'DoThat' { Write-Host "Performing 'DoThat' Action using FirstValue [$firstValue]" }
'Other' { Write-Host "Performing 'Other' Action using FirstValue [$firstValue]" }
Default {}
}
}
}
使用示例
PS > Test-OptionOrValue -Action DoThis -FirstValue 32
Action argument provided: DoThis
Only FirstValue required
FirstValue: 32
SecondValue:
Performing 'DoThis' Action using FirstValue [32]
PS > Test-OptionOrValue -Action DoThat -FirstValue 32
Action argument provided: DoThat
Only FirstValue required
FirstValue: 32
SecondValue:
Performing 'DoThat' Action using FirstValue [32]
PS > Test-OptionOrValue -FirstValue 12 -SecondValue 23
Both FirstValue and SecondValue required
FirstValue: 12
SecondValue: 23