Microsoft Graph API で差分取得(Delta Query) を試してみる

[ブログからの転載](https://1bed.allright.life/?p=3499)

## 経緯
別チームの仕事だけど、Microsoft Graph API を使って差分取得してのデータ同期とかいう楽しそうなことをやっていると聞いたので、興味が湧いたので少し試してみたいというのが動機

PowerShell で確認してみる（それぐらいなら Graph Explorer とか Postman 使えよという声も聞こえそうですががが）

## 環境

* Windows 10 Pro
* PowerShell 7.1.3

## 1. 前準備

PowerShell から Graph API を呼び出すために下記のことを行います
1. Azure AD にアプリの登録
2. アプリにアクセス許可
3. シークレットの発行を行い必要な情報を控える

### 1-1. Azure AD にアプリの登録

1. Azure Portal から Azure AD を開き、リソースメニュー **管理** から [ アプリの登録 ] をクリック
2. [ + 新規登録 ]をクリック
3. 下記のように入力して [ 登録 ] をクリック
   * 名前： Delta Query を試すゾ
   * サポートされているアカウントの種類： この組織ディレクトリのみに含まれるアカウント
   * リダイレクトURI：未入力

以上でアプリの登録は完了です

### 1-2. アプリにアクセス許可

1. 作成したアプリ **Delta Query を試すゾ** のリソースメニュー **管理** から [ API のアクセス許可 ] をクリック
2. [ Microsoft Graph ] をクリック  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_01h47_18-300x123.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_01h47_18.png)
3. [ アプリケーションの許可 ] をクリック
4. **User** 内の **User.Read.All** にチェックを入れ、[ アクセス許可の追加 ] をクリック  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_01h52_17-300x168.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_01h52_17.png)
5. 画面下の [エンタープライズ アプリケーション] をクリック  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_02h59_58-300x163.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_02h59_58.png)
6. [ {テナント名} に管理者の同意を与えます ] をクリック  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h03_54-300x152.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h03_54.png)
7. [ 承諾 ] をクリック  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h08_07-210x300.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h08_07.png)
8. [ 更新 ] をクリックして、管理者の同意が付与されていることを確認  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h14_48-300x160.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h14_48.png)

以上でアクセス許可は完了です

### 1-3. シークレットの発行を行い必要な情報を控える

1. 作成したアプリ **Delta Query を試すゾ** のリソースメニュー [ 概要 ] をクリックして、**アプリケーション (クライアント) ID** の値を控える  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_04h01_59-300x129.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_04h01_59.png)
2. リソースメニュー **管理** から [ 証明書とシークレット ] をクリック
3. クライアント シークレットの [ + 新しいクライアント シークレット ] をクリック  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h50_14-300x196.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h50_14.png)
4. 下記のように入力して [ 追加 ] をクリック
   * 説明： PowerShell で Delta Query を試す
   * 有効期限： 6か月 ※推奨らしい
5. **値** を控える  
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h54_22-300x192.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_03h54_22.png)

以上でシークレットの作成と、必要な情報を控えるは完了です

## 2. PowerShell で差分取得を試してみる

ここでは、手順 1 で控えた **アプリケーション (クライアント) ID** と **シークレットの値** を利用して Graph API を呼び出し、差分取得は Delta Query と呼ばれる方法で行う

1. 好きな方法で PowerShell 7 の起動
   [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_04h50_23-300x235.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-02_04h50_23.png)

2. 下記コマンドを実行して、Graph API のトークンを取得

    ```powershell
    $tenantDomain = "<組織名>.onmicrosoft.com" 
    $clientId     = "<手順 1-3 の 1 で取得したクライアントID>"
    $clientSecret = "<手順 1-3 の 5 で取得した値>"

    $body = @{
        Grant_Type    = "client_credentials"
        Scope         = "https://graph.microsoft.com/.default"
        client_Id     = $clientId
        Client_Secret = $clientSecret
    }

    $connectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantDomain/oauth2/v2.0/token" -Method POST 
-Body $body
    ```
   確認したところ、トークンは `access_token` に入っている

    ```
    $connectGraph
    ```
   結果例
   [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h35_20-300x29.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h35_20.png)

3. 下記コマンドを実行して、Delta Query でユーザー情報を取得

    ```powershell
    $token = $connectGraph.access_token
    $uri = "https://graph.microsoft.com/v1.0/users/delta"
    $headers = @{Authorization = "Bearer $($token)"}
    $response = Invoke-RestMethod -Method Get -Headers $headers -Uri $uri
    ```
  データが返ってきていることを確認

    ```powershell
    $connectGraph | Format-List *
    ```
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h46_02-300x203.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h46_02.png)
  value に値が入っているようなので、Azure AD のユーザー件数と比較したところ一致
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h54_44-300x40.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h54_44.png)
  [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h53_52-300x152.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_13h53_52.png)
4. nextLink を踏む

    ```powershell
    $nextLink = $response.'@odata.nextLink'
    $nextResponse = Invoke-WebRequest -Method GET -Headers $headers -Uri $nextLink
    ```
   レスポンスを確認したら、deltaLink というのがある

    ```powershell
    $nextResponse
    ```
   [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_14h28_31-300x106.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_14h28_31.png)
   この deltaLink を使って差分を確認する

5. デモユーザー11 を情報を修正して deltaLink を踏む

    ```powershell
    $deltaLink = ($nextResponse.Content | ConvertFrom-Json).'@odata.deltaLink'
    $updateResponse = Invoke-WebRequest -Method GET -Headers $headers -Uri $deltaLink
    ```
   レスポンスを確認

    ```powershell
    $deltaData = ($updateResponse.Content | ConvertFrom-Json)
    $deltaData | Format-List *
    ```
   [![](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_15h40_46-300x86.png)](https://1bed.allright.life/wp-content/uploads/2021/05/2021-05-03_15h40_46.png)
   更新したデモユーザー11が、value に入っている

## 考察

大体動き判ったので、次は色々なパターンで試してみる

## 参考

* https://docs.microsoft.com/ja-jp/graph/delta-query-users
* https://thesleepyadmins.com/2020/10/24/connecting-to-microsoft-graphapi-using-powershell/