Author Posts

August 26, 2014 at 5:12 am

Hello Folks,

I got a question about do and until

i'm creating a small script that checking if a file exist.
when the file no longer exist i need to copy a file to a new location.

for now i have.

do{
    Test-Path d:\test\test.log}
until($false)
{
    Copy-Item -path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
}

for now its do not care about true of false its just running endless till i stop the script.
can someone tell me how i need to fix this.

Thanks for the feedback

August 26, 2014 at 5:44 am

do {} until ($false) is an infinite loop; it'll only exit if you use something like break, return or throw from inside the loop body. do { } until ($true) would execute the loop body exactly once (which would make the loop rather pointless.)

It looks like what you intended to do was wait for a file to exist. For that, the code would look something like this:

while (-not (Test-Path d:\test\test.log))
{
    Start-Sleep -Milliseconds 100
}

# Do something with d:\test\test.log

I used a while loop instead of a do loop here, but the idea is the same; the loop condition is the result from Test-Path. I highly recommend putting a small sleep statement inside the loop body, as I've done here, so you don't just spin needlessly. A tenth of a second isn't much time in terms of user experience, but makes a massive difference to how fast you're banging away on the disk or CPU.

August 26, 2014 at 5:45 am

Based on the information you've provided, I think a while loop would work better for what you're trying to accomplish:

while (Test-Path -Path d:\test\test.log) {
    Copy-Item -Path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
}

With the while statement (or loop), the loop only runs if the condition evaluates to true.

A do-until loop checks the condition at the bottom of the loop, runs at least once, and is designed to continue as long as the condition is false. A do-while loop is similar to a do-until loop but repeats as long as the condition is true.

August 26, 2014 at 6:57 am

I modified my previous code to reverse the condition but it appears that it will not work because the loop only runs once and doesn't continue to test the condition to see if the file exists or not:

while (-not(Test-Path -Path d:\test\test.log)) {
    Copy-Item -Path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
}

I believe this will do the trick though:

do {
    if (Test-Path -Path d:\test\test.log -OutVariable Result) {
        Start-Sleep -Milliseconds 100
    }
    else {
        Copy-Item -Path 'd:\test\test.txt' -Destination 'd:\test\backup\test.txt'
    }
}
while ($Result)

August 26, 2014 at 11:20 pm

Thanks Dave and Mike,

It seems i'm using the wrong condition for the loop.
The following code is working i my case.

while (Test-Path -Path 'D:\test\test.loc')
{
    Start-Sleep -Milliseconds 100
}
Copy-Item -path 'D:\test\test.mdb' -Destination 'D:\Test\backup.mdb'

it was needed to check for a access DB lock file to disappear and copy the file for backup.