Private/Invoke-SPMWithRetry.ps1
|
function Invoke-SPMWithRetry { <# .SYNOPSIS Executes a script block and retries on SharePoint/Graph throttling (HTTP 429/503), honoring Retry-After. #> [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [scriptblock]$ScriptBlock, [int]$MaxRetries = 6 ) $attempt = 0 while ($true) { try { return & $ScriptBlock } catch { $attempt++ $status = $null $retryAfter = $null $response = $_.Exception.Response if ($response) { try { $status = [int]$response.StatusCode } catch { $status = $null } try { $values = @($response.Headers.GetValues('Retry-After')) if ($values.Count -gt 0) { $retryAfter = $values[0] } } catch { $retryAfter = $null } } if (-not $status -and $_.Exception.Message -match '(?i)429|too many requests|throttl|503|server too busy') { $status = 429 } if (($status -in 429, 503) -and $attempt -le $MaxRetries) { $delay = [Math]::Min(10 * $attempt, 120) $parsed = 0 if ($retryAfter -and [int]::TryParse([string]$retryAfter, [ref]$parsed) -and $parsed -gt 0) { $delay = $parsed } Write-Warning "Throttling (HTTP $status) - Versuch $attempt/$MaxRetries, warte $delay Sekunden..." Start-Sleep -Seconds $delay continue } throw } } } |