Reputation: 991
Basically I want to do a check if a directory exists then run this section, if not exit.
The script I have is:
$Path = Test-Path c:\temp\First
if ($Path -eq "False")
{
Write-Host "notthere" -ForegroundColor Yellow
}
elseif ($Path -eq "true")
{
Write-Host " what the smokes"
}
But it returns nothing.
Upvotes: 8
Views: 41442
Reputation: 200523
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
}
Upvotes: 5
Reputation: 7337
To make some things clear, always use Test-Path (or Test-Path with Leaf to check for a file).
Examples I've tested:
$File = "c:\path\file.exe"
$IsPath = Test-Path -Path $File -PathType Leaf
# using -Not or ! to check if a file doesn't exist
if (-Not(Test-Path -Path $File -PathType Leaf)) {
Write-Host "1 Not Found!"
}
if (!(Test-Path -Path $File -PathType Leaf)) {
Write-Host "2 Not Found!"
}
# using -Not or ! to check if a file doesn't exist with the result of Test-Path on a file
If (!$IsPath) {
Write-Host "3 Not Found!"
}
If (-Not $IsPath) {
Write-Host "4 Not Found!"
}
# $null checks must be to the left, why not keep same for all?
If ($true -eq $IsPath) {
Write-Host "1 Found!"
}
# Checking if true shorthand method
If ($IsPath) {
Write-Host "2 Found!"
}
if (Test-Path -Path $File -PathType Leaf) {
Write-Host "3 Found!"
}
Upvotes: 0
Reputation: 1711
If I'm not mistaken, one can simple say:
if($Path)
OR
if(!$Path)
But I might be wrong as I can't test atm.
Additionally there is the Test-Path
cmdlet available. Unfortunately I cannot describe the difference or suggest the most suitable method without knowing the case and scenario.
[EDITED TO CLARIFY ANSWER]
$Path = "C:\"
if($Path)
{
write-host "The path or file exists"
}
else
{
write-host "The path or file isn't there silly bear!"
}
Hope that adds clarity. With this method, no cmdlets needed. The returned boolean is interpreted for you automatically and runs code blocks if it meets the criteria of the test, in this case if the path C:\
exists. This would be true of files in longer file paths, C:\...\...\...\...\file.txt
Upvotes: 1
Reputation: 10017
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"
}
Upvotes: 17