Why is my boolean of value 0 returning true? Why is my boolean of value 0 returning true? powershell powershell

Why is my boolean of value 0 returning true?


This blog by Jeffrey Snover offers some insight on the behavior of booleans in Powershell. Below is an excerpt, where he creates a simple function "test" to return true or false depending on the input parameter:

PS> test "0"TRUEPS> test 0FALSEPS> test 1TRUEPS> test 0.0FALSEPS> test 0x0FALSEPS> test 0mbFALSEPS> test 0kbFALSEPS> test 0DFALSEPS> test 0.00000001TRUE

“0” is TRUE because it is a STRING and it has a length of 1. 0 is FALSE because it is a number and that number is 0. In PowerShell, any number which evaluates to 0 is FALSE and every non-zero number is TRUE. The example shows you a floating point zero, a hexadecimal zero, 0 megs, 0 kilos, 0 decimal, there are all sorts of zeros but to PowerShell, they all evaluate to FALSE.

Without any sample code it is hard to say exactly what is happening, but what we can say is that your input isn't being identified as zero by Powershell. Perhaps it is a string? This would be true if you used Read-Host to get user input. Here's an example:

PS C:\> $test = Read-Host "Input"Input: 0PS C:\> $test.GetType()IsPublic IsSerial Name                                     BaseType-------- -------- ----                                     --------True     True     String                                   System.ObjectPS C:\> test $testTRUEPS C:\> $test = [Int32]$testPS C:\> test $testFALSE

You can check by using GetType() on the variable in question, and fixing it may be a simple matter of explicitly casting to the desired type.

The more I read your question -- unless I've misunderstood it -- this seems to address your problems. Especially where you comment that you've been "passing in all sorts of different things" as any non-zero length string would evaluate to true in this context.

PS C:\> $anotherTest = "42"PS C:\> test $anotherTestTRUEPS C:\> $anotherTest = [Int32]$anotherTestPS C:\> test $anotherTestTRUE

Edit: Alright, I've worked a bit more on the problem now that I have some idea what your environment is. First, everything I told you above is true, so please don't disregard it. The problem you're experiencing is that the boolean type conversion is handling the powershell mandatory prompt input in a way that isn't immediately obvious.

So some situation exists where this code snippet:

param(    [Parameter(mandatory=$true)][bool]$myBool)Write-Host $myBool

Will cause the following result when you use powershell's mandatory parameter prompt instead of submitting the variable on the command line:

PS C:\> .\script.ps1 cmdlet script.ps1 at command pipeline position 1Supply values for the following parameters: myBool: 0 True

Let me re-iterate: In Powershell, all strings that are not of a null length evaluate to true. This includes "0", and this includes string literals. But what's the problem? We've already explicitly declared our variable as a bool, so it should understand that I mean 0, right?

Wrong. A rather unfortunate situation is created where we're expecting a bool, or at least a string, when we set our input to the prompt. We do indeed eventually get out bool, but remember what happens to non-null strings when we convert them to bools? The type conversion to bool is being applied to the literal input you set at the prompt, which is not a numeric type. Since the input is of a non-null length, the bool conversion evaluates to true. You are essentially performing this operation:

PS C:\> [bool]$myBool = [bool]"0"PS C:\> $myBoolTrue

The big problem with this is that since we've already converted our variable to a bool, the string has been consumed and we're just left with the value 1, or True. So your "0" literally turned into 1. We can't get the 0 back anymore. What should we do? I'll list a couple of options:

  • Set your variable as an [int] type instead of a [bool]. The bool conversion consumed the "0" string and turned it into a 1, so why not use a type that won't do that? Powershell understands numerical 0s and 1s to be true and false, so you can use any numerical type.

Example with output:

param(    [Parameter(mandatory=$true)][int]$myBool)Write-Host $myBoolPS C:\> .\script1.ps1cmdlet script1.ps1 at command pipeline position 1Supply values for the following parameters:myBool: 00
  • If you are using the bools as logic switches, consider the [switch] parameter type instead. Switches always evaluate to false unless you explicitly set them. You shouldn't ever expose the prompt this way, so you won't encounter this problem. More info here.


if your function is not accepting the parameters as boolean, that might explain why this is happening (Hyper Anthony explained it well).

So, does your script has param ([string]x1, [string[x2],[bool]y1,[bool]y2) type of declaration ? In that case y1 and y2 would be boolean, but if not may be getting treated as string with value 0, in which case it is treated like "0" which is not equal to 0