Powershell“;特别";开关参数

Powershell“;特别";开关参数,powershell,parameters,switch-statement,Powershell,Parameters,Switch Statement,我有下面的powershell函数 功能测试 { Param ( [参数()] [字符串]$Text=“默认文本” ) 写入主机“文本:$($Text)” } 我希望能够如下调用此函数: 测试-文本:应在主机上显示默认文本 测试-文本“另一个文本”:应在主机上显示提供的文本 我的问题是powershell中不允许使用第一种语法 有没有关于如何实现这个目标的想法? 我想要一种“switch”参数,它可以接受布尔值以外的值 谢谢您遇到的问题是参数绑定。PowerShe

我有下面的powershell函数

功能测试
{
Param
(               
[参数()]
[字符串]$Text=“默认文本”
)
写入主机“文本:$($Text)”
}
我希望能够如下调用此函数:

测试-文本:应在主机上显示默认文本

测试-文本“另一个文本”:应在主机上显示提供的文本

我的问题是powershell中不允许使用第一种语法

有没有关于如何实现这个目标的想法? 我想要一种“switch”参数,它可以接受布尔值以外的值


谢谢

您遇到的问题是参数绑定。PowerShell正在看到
[string]$Text
并需要一个值。您可以这样解决这个问题:

function Test {
    param(
        [switch]
        $Text,

        [Parameter(
            DontShow = $true,
            ValueFromRemainingArguments = $true
        )]
        [string]
        $value
    )

    if ($Text.IsPresent -and [string]::IsNullOrWhiteSpace($value)) {
        Write-Host 'Text : <default text here>'
    }
    elseif ($Text.IsPresent) {
        Write-Host "Text : $value"
    }
}
功能测试{
param(
[开关]
$Text,
[参数(
DontShow=$true,
ValueFromRemainingArguments=$true
)]
[字符串]
美元价值
)
if($Text.IsPresent-和[string]::IsNullOrWhiteSpace($value)){
写入主机“文本:”
}
elseif($Text.IsPresent){
写入主机“文本:$value”
}
}
注意:这是一个老套的解决方案,当参数未传递时,您应该只拥有一个默认值。

通过一个“捕获所有”参数为单个参数提供了一个解决方案,该参数通过RemainingArguments的
值收集所有位置传递的参数

但是,从根本上讲,PowerShell不支持您的要求:

自7.0起,PowerShell不支持带有可选值的参数-除了
[开关]
参数。

即:

  • 使用类型而不是
    [switch]
    声明的任何参数总是需要一个值
    (参数)

  • 唯一的其他选项是不加区别地收集带标记的参数中的任何未绑定位置参数,但是您将无法将这些参数与任何特定的其他绑定参数关联

换言之:

  • 如果恰好只需要一个可选参数,则RemainingArguments的
    值可以为您工作(除非您应该手动处理错误接收多个值的情况),如InCorrigible1的回答所示

  • 如果您有两个或更多这样的参数,那么这种方法就不切实际了:您必须知道参数的传递顺序(PowerShell不会告诉您),以便将剩余的位置参数与正确的参数相关联


使用
[switch]
参数(以想象中的
-Quiet
开关为例):

  • 如果您只是传递
    -Quiet
    ,则默认值为
    $true
  • $false
    通常通过根本不指定开关来表示(即忽略
    -Quiet
但是,您可以通过在开关名称后面加上
,然后加上布尔值来明确指定值:

  • -Quiet:$true
    与刚才的
    -Quiet

  • -Quiet:$false
    通常与省略
    -Quiet
    相同;但在极少数情况下,命令会区分省略的开关和具有显式
    $false
    值的开关;值得注意的是,允许使用
    -Confirm:$false
    -而不是省略
    -Confirm
    -来覆盖
    $ConfirmPreference
    首选项变量的值

所有参数都支持使用
作为参数名称与其参数之间的分隔符(与通常的空格字符相反),而
[switch]
参数则必须使用该分隔符,以便明确表示以下内容是开关参数的参数(默认情况下不需要参数)而不是一个独立的,定位的论点



上面的内容告诉我们,PowerShell已经具备了对可选参数的通用支持语法,因此在将来的某个时候,可以支持任何数据类型,如

中所建议的,只需添加另一个(可选)参数
$text2
并将
Position=0
添加到第一个参数中。@Theo这并没有回答问题。他们希望能够将
$Text
用作
字符串
开关
。您要问的不是PowerShell参数如何工作。也许你可以通过动态参数做你想做的事情,但是我看不出仅仅调用没有参数的函数来显示默认文本的问题。@TheIncorrigible1你确定吗?我现在很困惑。。使用第二个参数,您可以测试该参数是否有任何值,如果有,则忽略第一个默认参数并显示第二个参数。我以为这就是问题所在。@mklement0谢谢你的解释。我确实对开关使用冒号语法,但从未想过对其他类型的参数使用类似的语法。这是一个很好的解决方案!谢谢你:)!最后一个问题。如果我有第二个参数$Text1,它应该与$Text参数完全相同,该怎么办?我希望复制$Text和$Value的代码,并创建$Text1和$Value1,但有一个问题,因为如果我调用Test-Text-Text1“Hehe”,文本“Hehe”将被分配给$Value而不是$Value1。做得很好-这确实是您在PowerShell中可以做的最好的事情@Riana,此解决方法仅适用于单个可选参数。InCorrigible1使用带有默认值的常规参数无法实现所需的行为,因为基本的opt-in特性(参数是否已传递?)已丢失。这将非常好