次の方法で共有


Invoke-RestMethod を使用した Microsoft Graph API 要求でのエラーの処理

この記事では、PowerShell の Invoke-RestMethod コマンドレットを使用して Microsoft Graph API に要求を行うときにエラーを処理し、再試行ロジックを実装する方法を示すコード サンプルを提供します。

前提条件

  • クライアント シークレットを使用した Azure アプリの登録
  • Azure アプリの Microsoft.Graph の user.read.all アクセス許可。 詳細については、「 list users」を参照してください。

コード サンプル

再試行ロジックを示すために、このサンプルではゲスト ユーザーの signInActivity データのクエリを試みます。 このコードを実行すると、"403" エラーが発生する可能性があります。

  • Get-AccessTokenCC この関数は、Microsoft Entra ID (旧称 Azure Active Directory) からアクセス トークンを要求します。 トークンは、Microsoft Graph に対する API 要求を認証するために使用されます。 Azure 登録アプリの $clientSecret$clientId、および $tenantId 変数の値を指定する必要があります。
  • Get-GraphQueryOutput ($Uri) この関数は、Microsoft Graph API に対してデータの取得要求を行います。 ページングも処理します。 この関数は、"403" エラーが生成された場合に要求を再試行します。
Function Get-AccessTokenCC
 
{
    $clientSecret = ''
    $clientId = ''
    $tenantId = ''
    # Construct URI
    $uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
    # Construct Body
    $body = @{
        client_id = $clientId
        client_secret = $clientSecret
        scope = 'https://graph.microsoft.com/.default'
        grant_type = 'client_credentials'
    }
    # Get OAuth 2.0 Token
    $tokenRequest = Invoke-WebRequest -Method Post -Uri $uri -ContentType 'application/x-www-form-urlencoded' -Body $body -UseBasicParsing
    # Access Token
    $token = ($tokenRequest.Content | ConvertFrom-Json).access_token
    #$token = "Junk"  #uncomment this line to cause a 401 error -- you can set that status in the error handler to test the pause and retry
    #Write-Host "access_token = $token"
    return $token
}
 
Function Get-GraphQueryOutput ($Uri)
{
    write-host "uri = $Uri"
    write-host "token = $token"

    $retryCount = 0
    $maxRetries = 3
    $pauseDuration = 2
 
    $allRecords = @()
    while ($Uri -ne $null){
        Write-Host $Uri
        try {
            # todo: verify that the bearer token is still good -- hasn't expired yet -- if it has, then get a new token before making the request
            $result=Invoke-RestMethod -Method Get -Uri $Uri -ContentType 'application/json' -Headers @{Authorization = "Bearer $token"}
           
            Write-Host $result
         
            if($query.'@odata.nextLink'){
                # set the url to get the next page of records. For more information about paging, see https://docs.microsoft.com/graph/paging
                $Uri = $query.'@odata.nextLink'
            } else {
                $Uri = $null
            }
 
        } catch {
            Write-Host "StatusCode: " $_.Exception.Response.StatusCode.value__
            Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
 
            if($_.ErrorDetails.Message){
                Write-Host "Inner Error: $_.ErrorDetails.Message"
            }
 
            # check for a specific error so that we can retry the request otherwise, set the url to null so that we fall out of the loop
            if($_.Exception.Response.StatusCode.value__ -eq 403 ){
                # just ignore, leave the url the same to retry but pause first
                if($retryCount -ge $maxRetries){
                    # not going to retry again
                    $Uri = $null
                    Write-Host 'Not going to retry...'
                } else {
                    $retryCount += 1
                    Write-Host "Retry attempt $retryCount after a $pauseDuration second pause..."
                    Start-Sleep -Seconds $pauseDuration
                }
 
            } else {
                # not going to retry -- set the url to null to fall back out of the while loop
                $Uri = $null
            }
        }
    }
 
    $output = $allRecords | ConvertTo-Json

if ($result.PSObject.Properties.Name -contains "value") {
    return $result.value
} else {
    return $result
}
}
 
# Graph API URIs
$uri = 'https://graph.microsoft.com/v1.0/users?$filter=userType eq ''Guest''&$select=displayName,UserprincipalName,userType,identities,signInActivity'

# Pull Data
$token = Get-AccessTokenCC
Get-GraphQueryOutput -Uri $uri|out-file c:\\temp\\output.json

特定のヘッダーのキャプチャ

調整応答中に Retry-After などの特定のヘッダー値をキャプチャする (HTTP 429) などの高度なシナリオでは、次を使用します。

$retryAfterValue = $_.Exception.Response.Headers["Retry-After"]

"429 - 要求が多すぎます" エラーを処理するには、 Microsoft Graph 調整ガイダンスを参照してください。

お問い合わせはこちらから

質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。