0

I am trying to get my head around exception handling in Powershell, more specifically how to use a for loop to retry an action if it fails.

I have the code below, which catches the exception but will only attempt one iteration of the for loop.

Am I doing something wrong in my for loop? Or is this the behaviour of the catch block not to handle loops?

try{
        Copy-Item "C:\Path\To\Source.file" "C:\Path\To\Destination.file" -Force -ErrorAction Stop
    }
    catch{
        $e = $_.Exception.GetType().Name
        LogWrite $e
        if($e -eq 'IOException')
        {
            for($i=0; $i -lt 6; $i++)
            {
                LogWrite "Waiting..."
                Start-Sleep -s 10
                LogWrite "Copying in the file attempt $i" 
                Copy-Item "C:\Path\To\Source.file" "C:\Path\To\Destination.file" -Force
            }
        }            
    }
2
  • $e -eq 'IOException' gets false. What you see as "1 iteration" is LogWrite $e. Commented Feb 9, 2017 at 10:40
  • Thanks for reply, I think I understand what you mean that if the exception is not "IOException" it is returning false in my check and therefore not executing code inside for loop. I've used the code from the answer below as the logic makes a lot more sense for this scenario, but I was still expecting it to execute the for loop 5 times when $e -eq 'IOException' is true. Cheers for the help too! Commented Feb 9, 2017 at 14:14

1 Answer 1

2

You want to put the try/catch inside of a looping construct. Here's one way you might do it:

$i = 0
$done = $False
while(-not ($done) -and ($i -lt 6))
{
    try{
        Copy-Item "C:\Path\To\Source.file" "C:\Path\To\Destination.file" -Force -ErrorAction Stop
        $done = $True
    }
    catch{
        $e = $_.Exception.GetType().Name
        LogWrite $e
        if($e -eq 'IOException')
        {
            LogWrite "Waiting..."
            Start-Sleep -s 10
            LogWrite "Copying in the file attempt $i" 
            $i = $i + 1
        }
        else
        {
            $i = 6
        }
    }
}

In your current attempt, the second Copy-Item isn't contained in a try block, and catch blocks only catch exceptions that occur within their corresponding try.

(You then may want to do something after the loop if $i has reached 6, such as to report that you encountered an unrecoverable error)

Sign up to request clarification or add additional context in comments.

2 Comments

Cheers man, this makes a lot more sense. Also + for the done flag as I was wondering how I could either quit once successful or keep trying. Will give this code a go and see if I can expand on it.
Just to clarify, my original code should still have iterated each count of the for loop, but if it threw an exception on attempt one, it quits the for loop and moves on ? Sorry for confusing things, I just want to know why it wasn't counting past index 0 even after I caught the original exception. Powershell is pretty awesome.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.