$attempt = 0
do {
try {
# Do something that has a high possiblity to crash.
ping a
if (-not $LASTEXITCODE) {
$success = $true
} else {
throw "Transient error. LASTEXITCODE is $LASTEXITCODE."
}
}
catch {
if ($attempt -eq 5) {
# You can do some extra logging here.
Write-Error "Task failed. With all $attempt attempts. Error: $($Error[0])"
throw
}
Write-Host "Task failed. Attempt $attempt. Will retry in next $(5 * $attempt) seconds. Error: $($Error[0])" -ForegroundColor Yellow
Start-Sleep -Seconds $(5 * $attempt)
}
$attempt++
} until($success)
Running sample:
Failed:
PS C:\\Users\\AnduinXue\\Desktop> .\\test.ps1
Ping request could not find host a. Please check the name and try again.
Task failed. Attempt 0. Will retry in next 0 seconds. Error: Transient error. LASTEXITCODE is 1.
Ping request could not find host a. Please check the name and try again.
Task failed. Attempt 1. Will retry in next 5 seconds. Error: Transient error. LASTEXITCODE is 1.
Ping request could not find host a. Please check the name and try again.
Task failed. Attempt 2. Will retry in next 10 seconds. Error: Transient error. LASTEXITCODE is 1.
Ping request could not find host a. Please check the name and try again.
Task failed. Attempt 3. Will retry in next 15 seconds. Error: Transient error. LASTEXITCODE is 1.
Ping request could not find host a. Please check the name and try again.
Task failed. Attempt 4. Will retry in next 20 seconds. Error: Transient error. LASTEXITCODE is 1.
Ping request could not find host a. Please check the name and try again.
C:\\Users\\AnduinXue\\Desktop\\test.ps1 : Task failed. With all 5 attempts. Error: Transient error. LASTEXITCODE is 1.
At line:1 char:1
\+ .\\test.ps1
\+ ~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) \[Write-Error\], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1
Transient error. LASTEXITCODE is 1.
At C:\\Users\\AnduinXue\\Desktop\\test.ps1:10 char:13
\+ throw "Transient error. LASTEXITCODE is $LASTEXITCODE."
\+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Transient error. LASTEXITCODE is 1.:String) \[\], RuntimeException
+ FullyQualifiedErrorId : Transient error. LASTEXITCODE is 1.
Success one:
PS C:\\Users\\AnduinXue\\Desktop> .\\test.ps1
Pinging www.a.shifen.com \[112.80.248.75\] with 32 bytes of data:
Reply from 112.80.248.75: bytes=32 time=8ms TTL=56
Reply from 112.80.248.75: bytes=32 time=8ms TTL=56
Reply from 112.80.248.75: bytes=32 time=8ms TTL=56
Reply from 112.80.248.75: bytes=32 time=9ms TTL=56
Ping statistics for 112.80.248.75:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 8ms, Maximum = 9ms, Average = 8ms
I just finished reading your blog post on implementing a retry mechanism in PowerShell. I find the content very useful, and I appreciate the simplicity of the approach you've presented. The core idea of using a loop to retry a potentially failing operation is a great way to ensure the task's completion without manual intervention.
The example you have provided, which uses the "ping" command, is a good illustration of a transient error that might benefit from a retry mechanism. I particularly like how you have used the $LASTEXITCODE variable to check for success or failure and the Start-Sleep command to introduce a delay between retries. This makes the script more resilient and adaptable to different situations.
However, I noticed a small issue in your script. The
Start-Sleep -Seconds $(5 * $attempt)
command might cause an excessive delay in later retries, as it increases the waiting time exponentially. Instead, you could consider using a fixed delay between retries or using an incremental delay (e.g., 5 seconds for the first retry, 10 seconds for the second, etc.) to avoid excessive waiting times.In conclusion, your blog post provides a valuable and straightforward solution for implementing a retry mechanism in PowerShell. With some minor adjustments to the waiting time between retries, this script could become even more efficient and useful. Keep up the great work, and I look forward to reading more of your insightful blog posts in the future.