invoke-JobWithRetry.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID 07e4f49b-0836-47c7-9096-dcdf5e44004b .AUTHOR Jeffrey Snover .COMPANYNAME Microsoft .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION Invoke a scriptblock that may hang and need to be stopped and retried a number of times #> [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [scriptblock] $ScriptBlock, # How long a single scriptblock is allowed to run before being stopped/retried [Parameter()] $TimeoutPerTry = 30, # How long the function can run, in seconds, trying the ScriptBlock in a loop before returning. [Parameter()] $TotalTryTime = 120, # Number of seconds time to sleep between retries [Parameter()] $PauseBetweenRetries = 0 ) $trycount = 1 $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() do { $job = Start-Job -ScriptBlock $ScriptBlock $completedJob = Wait-Job -Job $job -Timeout $TimeoutPerTry if ($completedJob.State -eq 'Completed') { $output = Receive-Job -Job $completedJob Remove-Job -Job $completedJob return $output } else { Stop-Job -Job $job Remove-Job -Job $job Write-Verbose "Invoke-JobWithRetry: Try $tryCount did not complete" $tryCount++ Start-Sleep -Seconds $PauseBetweenRetries } } until ($stopwatch.Elapsed.TotalSeconds -ge $TotalTryTime) if ($completedJob.State -eq 'Failed') { Trace-Error -Message $completedJob.ChildJobs[0].JobStateInfo.Reason } elseif (-not $completedJob) { Write-Error -Message "Job failed, reason: the task did not complete within $TotalTryTime seconds." } |