2

I think I'm missing something obvious here. In my understanding a Boolean can only be 0, $False, 1 or $True. But when I try other integers, they are also accepted as $True.

When using other integers then 0 or 1 the function should throw an error saying that it's not a Boolean. Or should this be solved by adding error handling with ValidateSet for these 4 different input options?

Example:

Function Test-Bar {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True,Position=0)]
        [Bool]$Var
    )
    Write-Host "Yes, you entered a valid boolean: $Var" -ForegroundColor Yellow
}

[INT]$Number = '0'
Test-Bar -Var $Number

[INT]$Number = '1'
Test-Bar -Var $Number

[INT]$Number = '10'
Test-Bar -Var $Number # Incorrect, ten is not a boolean

[INT]$Number = '22'
Test-Bar -Var $Number # Incorrect, twenty two is not a boolean

Thank you for your help.

DarkLite1
  • 13,637
  • 40
  • 117
  • 214
  • 1
    FYI simply typing this `[bool]10` replicated this behaviour – Matt Feb 11 '15 at 13:51
  • Thanks for the heads-up Matt. But I really want my function to only accept `$True`, `$False`, `0` or `1` and nothing else. I thought this was possible with the `Boolean` type.. – DarkLite1 Feb 11 '15 at 13:54
  • Oh I understand. I was just trying to point out your function could be simplified for the purpose of testing. Doesnt really help but [this post](http://social.technet.microsoft.com/wiki/contents/articles/2286.understanding-booleans-in-powershell.aspx) says "And (usually) any non-zero integer evaluates as $true" – Matt Feb 11 '15 at 13:55
  • 2
    http://stackoverflow.com/a/18516573/3829407 links to a blog post that says: In PowerShell, any number which evaluates to 0 is FALSE and every non-zero number is TRUE. You need to account for this differently it seems. LIke `ValidateSet` – Matt Feb 11 '15 at 14:06

1 Answers1

2

I guess the [bool] type implicitly casts anything that's not $null, $false, 0 or an empty string as $true

> [bool]$true
True
> [bool]'foo'
True
> [bool]$false
False
> [bool]''
False
> [bool]$null
False

I'd have thought that in your case, using a SwitchParameter in your cmdletbinding would be suitable:

Function Test-Bar {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True,Position=0)]
        [Switch]$Var
    )
    Write-Host "Yes, you entered a valid boolean: $Var" -ForegroundColor Yellow
}

And call like:

> Test-Bar -var
Yes, you entered a valid boolean: True
> Test-Bar -var:$false
Yes, you entered a valid boolean: False

You may also want to look at the answers on this question which discuss ways to test/convert to boolean if you really have to.

Community
  • 1
  • 1
arco444
  • 22,002
  • 12
  • 63
  • 67
  • This does not work given the constraints of the OP. `Test-Bar 0` and `Test-Bar 1` fail. – Matt Feb 11 '15 at 14:02
  • @Matt I realise that, this is intended as an alternative approach. The `switch` parameter, as far as I can tell, exists for precisely this scenario – arco444 Feb 11 '15 at 14:03
  • After checking your suggestion and Matt's documentation, it seems indeed adviced to just use the `Switch` parameter. I only need to figure out to transform `0` to `$False` and `1` to `$True` before I fill the splatting hash table to feed the function. Thank you guys, I was apparently wrong about `Booleans`. – DarkLite1 Feb 11 '15 at 14:11