Videos
This does not work like that:
if(isInt($value) -eq $false){ write-output "Invalid" }
Wrap it as it is it’s own
if((isInt($value)) -eq $false){ write-output "Invalid" }
^ this should work
I’m starting to feel really dumb. I have a simple function to test whether a variable contains an integer:
function isInt ($value)
{
$valid = $false
if($value -match "^[0-9]+$"){
$valid = $true
}
return $valid
}
I can then use a if statement/block to test:
$value = 4
if(isInt($value) -eq $true){
write-output "Valid"
}else{
write-output "Invalid"
}
This correctly outputs “Valid”. If I change $value to a non-integer, it correctly outputs “Invalid” when I run the above code.
All fine and good.
However, if I only want to check and run code for invalid integers (doing nothing for valid ones), the following IF statement returns nothing regardless of the $value’s value:
PS>$value = "abc"
PS>if(isInt($value) -eq $false){ write-output "Invalid" }
PS>
Yet just running the isInt function does return False
PS>isInt($value)
False
If I change $value to an valid integer, it outputs “Invalid”
PS>$value = 2
PS>if(isInt($value) -eq $false){ write-output "Invalid" }
Invalid
And isInt by itself shows True
PS>isInt($value)
True
What am I misunderstanding/getting wrong here? I feel the function isn’t actually returning $false but something else.
The error comes from the fact that the return value of Test-Path is a Boolean type.
Hence, don't compare it to strings representation of Boolean but rather to the actual $false/$true values. Like so,
$Path = Test-Path c:\temp\First
if ($Path -eq $false)
{
Write-Host "notthere" -ForegroundColor Yellow
}
elseif ($Path -eq $true)
{
Write-Host " what the smokes"
}
Also, note that here you could use an else statement here.
Alternatively, you could use the syntax proposed in @user9569124 answer,
$Path = Test-Path c:\temp\First
if (!$Path)
{
Write-Host "notthere" -ForegroundColor Yellow
}
elseif ($Path)
{
Write-Host " what the smokes"
}
In a comparison operation PowerShell automatically converts the second operand to the type of the first operand. Since you're comparing a boolean value to a string, the string will be cast to a boolean value. Empty strings will be cast to $false and non-empty strings will be cast to $true. Jeffrey Snover wrote an article "Boolean Values and Operators" about these automatic conversions that you can check for further details.
As a result this behavior has the (seemingly paradox) effect that each of your comparisons will evaluate to the value of your variable:
PS C:\> $false -eq 'False' False PS C:\> $false -eq 'True' False PS C:\> $true -eq 'False' True PS C:\> $true -eq 'True' True
Essentially that means that if your Test-Path statements evaluates to $false neither of your conditions will match.
As others have pointed out you can fix the issue by comparing your variable to actual boolean values, or by just using the variable by itself (since it already contains a boolean value that can be evaluated directly). However, you need to be careful with the latter approach. In this case it won't make a difference, but in other situations automatic conversion of different values to the same boolean value might not be the desired behavior. For instance, $null, 0, empty string and empty array are all interpreted as a boolean value $false, but can have quite different semantics depending on the logic in your code.
Also, there is no need to store the result of Test-Path in a variable first. You can put the expression directly into the condition. And since there are only two possible values (a file/folder either exists or doesn't exist), there is no need to compare twice, so your code could be reduced to something like this:
if (Test-Path 'C:\temp\First') {
Write-Host 'what the smokes'
} else {
Write-Host 'notthere' -ForegroundColor Yellow
}
Source: https://github.com/Esri/arcgis-powershell-dsc/blob/main/Modules/ArcGIS/ArcGIS.psm1
Lines 1953 and 1973 specifically.
I am looking at some powershell code (link above), and don't understand why a simple boolean check is written as:
$JobFlag = $True
# more code here...
if ($JobFlag[$JobFlag.Count - 1] -eq $True) { # CODE HERE }There are some functions that might be called before the if-statement, but as far as I can tell, they return either $True or $False
Is there any reason for not writing a plain:
if ($JobFlag -eq $True)
I am by now means an experienced powershell user, therefore curious.