Why is my boolean of value 0 returning true?

Question:

I’ve been working on some PowerShell scripts and found something a little odd.
I have a script that accepts 4 mandatory parameters: two strings and two Booleans.

.\[scriptname] [string1] [string2] [bool1] [bool2]

This works fine, and I’ve checked that they are all being passed correctly.

However, I’ve found something rather strange when PowerShell asks for parameters; it sets both booleans to true.

It then runs the script as if bool1 and bool2 were set to true, and not to what I’ve set them to. I have true passing in all sorts of different things, and it always results in true.

I’m unsure as to why this is happening, and wanted to know if anyone has come across a cause or solution to this bizarre problem!

I’ve also found that the Task Scheduler has a similar issue.
Set it up with

powershell -file [scriptlocation] [string1] [string2] [bool1] [bool2]

example:

powershell -file “C:\script1.ps1” “c:\fileOne.txt” “c:\folder1” 0 0

Both booleans come through as strings.

Answer:

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:

“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:

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.


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:

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

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:

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:

  • 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.

Source:

Why is my boolean of value 0 returning true? by licensed under CC BY-SA | With most appropriate answer!

Leave a Reply