Consider the following function :
function myfunc()
{
if (condition1) {
return 'nowork'
} elseif (condition2) {
return $false
} elseif (condition3) {
return $true
}
Now if I call this function, and I know that condition3 is true, I can see that True is returned:
...
$result = myfunc
Write-Host $result
(this writes True to the console.)
The next statement in the calling function is an if statement to determine what was returned, and act upon that:
$result = myfunc
Write-Host $result
if ($result -eq 'nowork') {
do this..
} elseif ($result -eq $false) {
do that..
} elseif ($result -eq $true) {
do something else..
}
And this is where it gets strange (to me). Even though I can see that True is returned, the if statement decides to go do 'do this..', the first branch of the if statement, where I would have expected that 'do something else..' would have been done. Another strange thing is that it sometimes works, sometimes not. I tried changing the if statement to:
if ('nowork' -eq $result)
and then what went wrong first now worked, but later on the same issue re-appeared.
I'm guessing there's something wrong with my first string comparison, but I can't figure out what. I'm used to writing scripts in Linux (bash), so Powershell must be acting differently.
Btw: script is run in Debian 10, Powershell 7, but the exact same problem also appears on a Windows machine with Powershell 5.0.
Please help..
PowerShell's comparison operator behavior depends on type of the left-hand side operand.
When your lhs ($result
) is a [bool]
(ie. $true
or $false
), PowerShell will attempt to convert the right-hand side operand to [bool]
as well before comparing the two.
Converting a non-empty string (ie. 'nowork'
) to [bool]
results in $true
, so the if
condition evaluates to $true -eq $true
-> $true
.
You can fix this by manually type checking:
if($result -is [bool]){
if($result){
# was $true
}
else {
# was $false
}
}
elseif($result -eq 'nowork'){
# was 'nowork'
}
The nicer way of solving this however would be to always return the same type of object. In your case where you have 3 different return options, consider an enum
:
enum WorkAmount
{
None
Some
All
}
function myfunc()
{
if (condition1) {
return [WorkAmount]::None
} elseif (condition2) {
return [WorkAmount]::Some
} elseif (condition3) {
return [WorkAmount]::All
}
}