8

Given this basic function:

Function TestFunction {
    Param ( [int]$Par1, [string]$Par2, [string]$Par3 )
    If ($Par1 -ne $Null) { Write-Output "Par1 = $Par1" }
    If ($Par2 -ne $Null -or $Par2 -ne '') { Write-Output "Par2 = $Par2" }
    If ($Par3 -ne $Null) { Write-Output "Par3 = $Par3" }
}
TestFunction -Par1 1 -Par3 'par3'

...the output is:

Par1 = 1
Par2 = 
Par3 = par3

Even though I didn't pass anything into the $Par2 variable, it still isn't Null or empty. What happened, and how can I rewrite the statement so that the second If-statement evaluates as False and the script-block does not get executed?

(I added the -or $Par2 -ne '' just to test, it behaves the same with and without it.)

2 Answers 2

13

You have a logic error in your program: $Par2 will always be not equal to $null or not equal to ''.

To fix the logic, you should use -and instead of -or here:

If ($Par2 -ne $Null -and $Par2 -ne '') { Write-Output "Par2 = $Par2" }

However, because you casted the $Par2 argument to a string in the function's argument list:

Param ( [int]$Par1, [string]$Par2, [string]$Par3 )
                    ^^^^^^^^

the check for $Par2 -ne $Null is unnecessary since $Par2 will always be of type string (if you do not give it a value, it will be assigned to ''). So, you should actually write:

If ($Par2 -ne '') { Write-Output "Par2 = $Par2" }

Or, because '' evaluates to false, you might just do:

If ($Par2) { Write-Output "Par2 = $Par2" }
Sign up to request clarification or add additional context in comments.

5 Comments

That was fast. But what is actually IN $Par2? If I pass a value into it, $Par2 -ne $Null will be true. But if I pass nothing into it $Par2 -ne $Null should be false and should not be executed, right? And yet, it does...
See my edit. $Par2 will always be a string because you casted it to one in the function's argument list. Also, for future, you can get the type of any variable using the GetType method: $Par2.GetType(). This will greatly aid in debugging.
So, because I casted it in the parameter-block, it will always exist and therefor never be null? Even if I were to change the default value into null ([string]$Par2 = $Null)? And an integer will always be 0? So if I were to pass nothing into $par1, then If ($Par1) will be true because it contains 0? So in trying to write a better script by casting the variable-types, I actually made it more difficult for myself.
Yes, that is correct. $Par2 will never be $null because you casted it to a string. Even if you do [string]$Par2 = $Null, it will still be assigned to '' (you can test this using $Par2.GetType()). And yes, [int]$Par1 = $Null will make $Par1 become 0. However, If ($Par1) will not be true because 0 evaluates to false in a boolean context (all other numbers evaluate to true).
I think I get it, thank you. You saved me from a headache. For completeness in this thread, I just discovered [string]$Par2 = [System.Management.Automation.Language.NullString]::Value to turn a string into null after all, now that I have an idea what to Google for. Although that doesn't work for integers.
1

You can check that (check if $variablename has $null as value):

if (!$variablename) { Write-Host "variable is null" }

And if you wanna check if $variablename has any value except $null:

if ($variablename) { Write-Host "variable is NOT null" }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.