1

Very new to coding in general, so I fear I am missing something completely obvious. I want my program to check for a file. If it is there, just continue the code. If it has not arrived, continue cheking for a given amount of time, or untill the file shows up. My loop works on its own, so when i only select the do-part in Powershell ISE, it works. But when i try running it inside the if statement, nothing happens. The loops doesnt begin.

$exists= Test-Path $resultFile 
$a = 1 

if ($exists -eq "False")
{ 
do 
    {
    $a++
    log "Now `$a is $a "
    start-sleep -s ($a)
    $exists= Test-Path $resultFile 
    write-host "exists = $exists"                
    }
    while (($a -le 5) -and ($exists -ne "True"))       
 }
Ullsokk
  • 697
  • 2
  • 11
  • 24
  • 8
    `"True"` -> `$true` and most important `"False"` -> `$false`. – user4003407 Nov 17 '15 at 12:42
  • 2
    Possible duplicate of [Why does '$true -eq "string"' returns $true?](http://stackoverflow.com/questions/26545686/why-does-true-eq-string-returns-true) – Matt Nov 17 '15 at 13:41
  • FYI instead of `"True"` and `"False"` (which are both strings), use `$true` and `$false` as these contain the actual Boolean values. – Deadly-Bagel Nov 17 '15 at 15:40

2 Answers2

3

Another way of doing this is using a while loop:

$VerbosePreference = 'Continue'

$file = 'S:\myFile.txt'
$maxRetries = 5; $retryCount = 0; $completed = $false

while (-not $completed) {
    if (Test-Path -LiteralPath $file) {
        Write-Verbose "File '$file' found"
        $completed = $true
        
        # Do actions with your file here
    }
    else {
        if ($retryCount -ge $maxRetries) {
            throw "Failed finding the file within '$maxRetries' retries"
        } else {
            Write-Verbose "File not found, retrying in 5 seconds."
            Start-Sleep '5'
            $retryCount++
        }
    }
}

Some tips:

  • Try to avoid Write-Host as it kills puppies and the pipeline (Don Jones). Better would be, if it's meant for viewing the script's progress, to use Write-Verbose.
  • Try to be consistent in spacing. The longer and more complex your scripts become, the more difficult it will be to read and understand them. Especially when others need to help you. For this reason, proper spacing helps all of us.
  • Try to use Tab completion in the PowerShell ISE. When you type start and press the TAB-key, it will automatically propose the options available. When you select what you want with the arrow down/up and press enter, it will nicely format the CmdLet to Start-Sleep.
  • The most important tip of all: keep exploring! The more you try and play with PowerShell, the better you'll get at it.
DarkLite1
  • 13,637
  • 40
  • 117
  • 214
  • Thank you! Those were some great tips. Also, I see how a lot of my variables have a "best practice" naming - such at MaxRetries and RetryCount. I will be using more standard nomenclature forward. Also, I think I might be best served using do until instead of do while. Makes more sense I guess, even if the end result is the same. – Ullsokk Nov 18 '15 at 08:24
  • You're welcome, glad it helped you out :) PowerShell is a super flexible language. So if you feel more comfortable in using `do until`, then please do so. – DarkLite1 Nov 18 '15 at 09:04
2

As pointed out in comments, your problem is that you're comparing a boolean value with the string "False":

$exists -eq "False"

In PowerShell, comparison operators evaluate arguments from left-to-right, and the type of the left-hand argument determines the type of comparison being made.

Since the left-hand argument ($exists) has the type [bool] (a boolean value, it can be $true or $false), PowerShell tries to convert the right-hand argument to a [bool] as well.

PowerShell interprets any non-empty string as $true, so the statement:

$exists -eq "False"

is equivalent to

$exists -eq $true

Which is probably not what you intended.

Community
  • 1
  • 1
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206