在PowerShell中安全地将字符串转换为bool

时间:2014-12-15 13:00:04

标签: powershell boolean tryparse

我正在尝试将PowerShell脚本的参数转换为布尔值。这一行

[System.Convert]::ToBoolean($a)
只要我使用诸如“true”或“false”的有效值,

就可以正常工作,但是当传递无效值(例如“bla”或“”)时,将返回错误。我需要类似于TryParse的东西,如果输入值无效则将值设置为false并返回指示转换成功或失败的布尔值。 为了记录,我尝试了[boolean] :: TryParse和[bool] :: TryParse,PowerShell似乎没有认出来。

现在我不得不通过两个额外的if语句来笨拙地处理这个问题。

让我感到惊讶的是,到目前为止,我发现的任何方法和博客文章都没有处理无效值。 我是否遗漏了一些东西,或者PowerShell孩子对于输入验证来说太酷了?

6 个答案:

答案 0 :(得分:16)

您可以使用try / catch块:

$a = "bla"
try {
  $result = [System.Convert]::ToBoolean($a) 
} catch [FormatException] {
  $result = $false
}

给出:

> $result
False

答案 1 :(得分:10)

只要您使用TryParse并首先声明变量,

ref就可以正常工作:

$out = $null
if ([bool]::TryParse($a, [ref]$out)) {
    # parsed to a boolean
    Write-Host "Value: $out"
} else {
    Write-Host "Input is not boolean: $a"
}

答案 2 :(得分:5)

$a = 'bla'
$a = ($a -eq [bool]::TrueString).tostring()
$a

False

答案 3 :(得分:1)

另一种可能性是使用切换状态,仅评估True1default

$a = "Bla"
$ret = switch ($a) { {$_ -eq 1 -or $_ -eq  "True"}{$True} default{$false}}

如果字符串等于True $true,则返回此值。在所有其他情况下,都会返回$false

另一种方法是:

@{$true="True";$false="False"}[$a -eq "True" -or $a -eq 1]

来源Ternary operator in PowerShell by Jon Friesen

答案 4 :(得分:1)

再次寻找这个并找到了我自己的答案 - 但是作为一个评论,所以添加了一些修正/其他输入值的答案,还有一个pester测试来验证它是否按预期工作:

Function ParseBool{
    [CmdletBinding()]
    param(
        [Parameter(Position=0)]
        [System.String]$inputVal
    )
    switch -regex ($inputVal.Trim())
    {
        "^(1|true|yes|on|enabled)$" { $true }

        default { $false }
    }
}

Describe "ParseBool Testing" {
    $testcases = @(
        @{ TestValue = '1'; Expected = $true },
        @{ TestValue = ' true'; Expected = $true },
        @{ TestValue = 'true '; Expected = $true },
        @{ TestValue = 'true'; Expected = $true },
        @{ TestValue = 'True'; Expected = $true },
        @{ TestValue = 'yes'; Expected = $true },
        @{ TestValue = 'Yes'; Expected = $true },
        @{ TestValue = 'on'; Expected = $true },
        @{ TestValue = 'On'; Expected = $true },
        @{ TestValue = 'enabled'; Expected = $true },
        @{ TestValue = 'Enabled'; Expected = $true },

        @{ TestValue = $null; Expected = $false },
        @{ TestValue = ''; Expected = $false },
        @{ TestValue = '0'; Expected = $false },
        @{ TestValue = ' false'; Expected = $false },
        @{ TestValue = 'false '; Expected = $false },
        @{ TestValue = 'false'; Expected = $false },
        @{ TestValue = 'False'; Expected = $false },
        @{ TestValue = 'no'; Expected = $false },
        @{ TestValue = 'No'; Expected = $false },
        @{ TestValue = 'off'; Expected = $false },
        @{ TestValue = 'Off'; Expected = $false },
        @{ TestValue = 'disabled'; Expected = $false },
        @{ TestValue = 'Disabled'; Expected = $false }
    )


    It 'input <TestValue> parses as <Expected>' -TestCases $testCases {
        param ($TestValue, $Expected)
        ParseBool $TestValue | Should Be $Expected
    }
}

答案 5 :(得分:1)

先前的答案较为完整,但是如果您知道$foo -eq 1, "1", 0, "0", $true, $false...可以强制使用[int]

的任何内容,

以下statements中的任何一项均可工作:

[System.Convert]::ToBoolean([int]$foo)
[System.Convert]::ToBoolean(0 + $foo)

希望可以帮助只需要简单解决方案的人。