Functions/Invoke-GraphAPI.ps1
|
<#
.SYNOPSIS Invokes the Microsoft Graph API with the provided URI and access token. .DESCRIPTION This function calls the Microsoft Graph API with the provided URI and access token. It handles pagination and retries in case of throttling or unauthorized responses. .PARAMETER Uri The URI of the Microsoft Graph API endpoint to call. .PARAMETER Method The HTTP method to use for the API call (e.g. GET, POST, etc.). .PARAMETER ODataQuery An optional OData query to include in the API call. .EXAMPLE $response = Invoke-GraphAPI -Uri "https://graph.microsoft.com/v1.0/users" -Method "GET" Returns a response object containing information about the users in the organization. #> function Invoke-GraphAPI { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Uri, [string]$Method, [Parameter(Mandatory = $false)] [string]$ODataQuery ) Begin { $ErrorActionPreference = 'Stop' $now = Get-Date $retryCount = 0 [int]$MaxRetries = 3 [int]$RetryDelaySeconds = 3 } Process { # Check if access token is still valid if ($null -eq $global:AzureADAccessToken -or $global:AzureADAccessTokenExpiration -lt $now) { Write-Host "Access token is not valid. Please run the Get-AzureADAccessToken cmdlet again." return } # Call the Graph API with the access token $headers = @{ 'Authorization' = "Bearer $($global:AzureADAccessToken)" } do { try { $response = Invoke-RestMethod -Uri $Uri -Headers $headers -Method $Method # Handle pagination while ($response.'@odata.nextLink' -or ($response.'@odata.nextLink' -and ($nextResponse.value.Length -gt 0))) { $nextLink = $response.'@odata.nextLink' if($nextResponse.value.Length -eq 0){ write-host "Empty value array, breaking out of loop" break} write-host "Next link is: " $nextLink $nextResponse = Invoke-RestMethod -Uri $nextLink -Headers $headers $response.value += $nextResponse.value $response.'@odata.nextLink' = $nextResponse.'@odata.nextLink' } return $response } catch { $statusCode = $_.Exception.Response.StatusCode switch ($statusCode) { 429 { if ($retryCount -lt $MaxRetries) { Write-Host "Throttled. Retrying in $RetryDelaySeconds seconds..." Start-Sleep -Seconds $RetryDelaySeconds $retryCount++ continue } else { throw $_ } } NotFound { Write-Host "HTTP returned a 404 not found response for the provided endpoint: " write-host $Uri return $response.Error.Message break } Unauthorized { Write-Host "HTTP returned a 401 unauthorized response for the provided endpoint: " write-host $Uri write-host "RequestID is: " $response.headers $retryCount++ start-sleep -Seconds $RetryDelaySeconds write-host "Retrying...the current retry count is $retryCount" continue } BadRequest{ Write-Host "HTTP returned a 400 bad request response for the provided endpoint: " write-host $Uri return $response.Error.Message break } default { throw $_ } } } }while ($retryCount -lt $MaxRetries) } end { if ($retryCount -eq $MaxRetries) { write-host "Max retries exceeded. Exiting script." exit } } } |