【问题标题】:Why this code passing switch parameters to a PowerShell function fails为什么此代码将开关参数传递给 PowerShell 函数会失败
【发布时间】:2015-01-14 08:49:57
【问题描述】:

这个问题是关于传递开关参数的。让我们看看代码。我有这个 PowerShell 3.0 功能:

#test1.ps1
param(
    [switch] $param1 = $false
)

Write-Host "param1: $($param1.IsPresent)"
Write-Host

我有这个主要的 PowerShell 函数,它以四种不同的方式调用 test.ps1:

#Test0.ps1
cls

$param1 = $True

# 1
.\test1.ps1 -param1

# 2
.\test1.ps1 -param1:$true

# 3
$potato = "-param1:`$$($param1)"
Write-Host "Parameter value: $potato" 
.\test1.ps1 $potato

# 4
$command = ".\test1.ps1 -param1:`$$($param1)"
Write-Host "Command: $command" 
iex $command

exit

为什么第 3 种方法会失败?我知道我可以用第 4 种方法,但我很想了解为什么第 3 种方法会失败。

这是输出。结果所有参数都应该是 True 但第三个是 False...

param1: True

param1: True

Parameter value: -param1:$True
param1: False

Command: .\test1.ps1 -param1:$True
param1: True

【问题讨论】:

    标签: powershell parameters powershell-3.0


    【解决方案1】:

    会发生什么:

    1. 解析器查看提供的参数:"-param1:$true"
    2. 未能将其绑定到参数param1,因为您提供的值是string,而不是开关/布尔值
    3. 位置 0 不需要特定的参数类型,参数被忽略

    如果您将param1 设置为位置,您可以看到 PowerShell 如何无法正确绑定它:

    function test-parambinding {param([Parameter(Position=0)][switch]$param1);$param1.IsPresent}
    test-parambinding "-param1:`$true"
    

    你会看到ParameterArgumentTransformationException在其他任何事情发生之前抛出

    【讨论】:

    • 嗯,是的,当你将它转换为布尔值时,非空字符串将被视为$True
    【解决方案2】:

    Mathias 解释了为什么您的第三种传递参数方式会失败,但是还有另一种传递参数的方式可以让您大致执行您在此处尝试的操作。

    我在这里使用了一个函数,因为调用它时键入的内容少了一点,但您的脚本文件将照常工作:

    PS C:\> function test1() {
    param(
        [switch] $param1 = $false
    )
    
    Write-Host "param1: $($param1.IsPresent)"
    Write-Host
    }
    
    PS C:\> $param1 = $True
    PS C:\> $potato = @{'param1'=$param1}
    
    PS C:\> $potato
    
    Name                           Value                                                                                                  
    ----                           -----                                                                                                  
    param1                         True                                                                                                   
    
    
    
    PS C:\> test1 @potato
    param1: True
    

    因此,不要将参数和值作为单个字符串传递,而是创建一个以参数名称作为键、参数作为值的哈希。然后使用@ splatting 运算符调用函数或脚本。 (详情请参阅help about_Splatting)。

    【讨论】:

    • +1:这不是直接回答问题(为什么会失败),而是提供了一个非常有趣的选择
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    相关资源
    最近更新 更多