Private/Invoke-MgGraphRequestWithRetry.ps1
|
function Invoke-MgGraphRequestWithRetry { <# .SYNOPSIS Wraps Invoke-MgGraphRequest with automatic retry on HTTP 429 (Too Many Requests). .DESCRIPTION Calls Invoke-MgGraphRequest and retries up to MaxRetries times when a 429 throttling response is received. Uses the Retry-After header value when available, falling back to exponential back-off (2^attempt seconds). .PARAMETER Method The HTTP method (GET, POST, PATCH, DELETE, etc.). .PARAMETER Uri The Graph API URI to call. .PARAMETER Body Optional request body (for POST/PATCH). .PARAMETER MaxRetries Maximum number of retry attempts on 429 responses. Defaults to 3. #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet('GET', 'POST', 'PUT', 'PATCH', 'DELETE')] [string]$Method, [Parameter(Mandatory)] [string]$Uri, [Parameter()] [object]$Body, [Parameter()] [ValidateRange(0, 10)] [int]$MaxRetries = 3 ) $attempt = 0 while ($true) { try { $params = @{ Method = $Method Uri = $Uri } if ($PSBoundParameters.ContainsKey('Body')) { $params['Body'] = $Body } return Invoke-MgGraphRequest @params } catch { $statusCode = $null # Extract HTTP status code from the exception if ($_.Exception.Response) { $statusCode = [int]$_.Exception.Response.StatusCode } elseif ($_.Exception.Message -match '\b429\b') { $statusCode = 429 } if ($statusCode -eq 429 -and $attempt -lt $MaxRetries) { $attempt++ # Use Retry-After header if available, otherwise exponential back-off $retryAfterSeconds = [math]::Pow(2, $attempt) if ($_.Exception.Response.Headers) { try { $retryHeader = $_.Exception.Response.Headers | Where-Object { $_.Key -eq 'Retry-After' } | Select-Object -ExpandProperty Value -First 1 if ($retryHeader) { $retryAfterSeconds = [int]$retryHeader } } catch { # Ignore header parsing errors; use default back-off } } Write-Warning "Request throttled (HTTP 429). Retrying in $retryAfterSeconds seconds (attempt $attempt of $MaxRetries)..." Start-Sleep -Seconds $retryAfterSeconds } else { # Not a 429 or retries exhausted — re-throw throw } } } } |