web-dev-qa-db-fra.com

Conversion sécurisée de chaîne en bool dans PowerShell

J'essaie de convertir un argument de mon script PowerShell en valeur booléenne. Cette ligne

[System.Convert]::ToBoolean($a)

fonctionne bien tant que j'utilise des valeurs valides telles que "true" ou "false", mais lorsqu'une valeur non valide, telle que "bla" ou "" est transmise, une erreur est renvoyée. J'ai besoin de quelque chose de similaire à TryParse, qui définirait simplement la valeur sur false si la valeur d'entrée n'est pas valide et renvoie un booléen indiquant le succès ou l'échec de la conversion. Pour mémoire, j'ai essayé [boolean] :: TryParse et [bool] :: TryParse, PowerShell ne semble pas le reconnaître.

En ce moment, je dois gérer maladroitement cela en ayant deux instructions if supplémentaires.

Ce qui m'a surpris qu'aucun des tutoriels et articles de blog que j'ai trouvés jusqu'à présent ne traite des valeurs non valides. Suis-je en train de manquer quelque chose ou les enfants PowerShell sont-ils tout simplement trop cool pour la validation des entrées?

14
Shaggydog

Vous pouvez utiliser un bloc try/catch:

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

Donne:

> $result
False
18
arco444

TryParse devrait fonctionner tant que vous utilisez ref et déclarez la variable en premier:

$out = $null
if ([bool]::TryParse($a, [ref]$out)) {
    # parsed to a boolean
    Write-Host "Value: $out"
} else {
    Write-Host "Input is not boolean: $a"
}
15
Mike Zboray
$a = 'bla'
$a = ($a -eq [bool]::TrueString).tostring()
$a

False
6
mjolinor

je viens de chercher cela à nouveau et j'ai trouvé ma propre réponse - mais en tant que commentaire, ajouter comme réponse avec quelques corrections/autres valeurs d'entrée et également un test de nuisance pour vérifier que cela fonctionne comme prévu:

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
    }
}
2
David Wallis

Une autre possibilité consiste à utiliser le commutateur statemement et à n'évaluer que True, 1 et default:

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

Dans ce cas, si la chaîne est égale à True$true est renvoyé. Dans tous les autres cas $false est renvoyé.

Et une autre façon de le faire est la suivante:

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

Source opérateur ternaire dans PowerShell par Jon Friesen

2
Micky Balladelli

Les réponses précédentes sont plus complètes, mais si vous savez que $foo -eq 1, "1", 0, "0", $true, $false... tout ce qui peut être contraint à un [int]

L'un des statements travaux suivants:

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

J'espère que cela aide quelqu'un qui a juste besoin d'une solution simple.

1
Todd Bleeker