Entra ID のAPI駆動型インバウンドプロビジョニングをやってみた - その2

1.はじめに
Entra ID のAPI駆動型インバウンドプロビジョニングを、PowershellとCSVを使ってプロビジョニングする記事がなかったので自分の備忘として残します。

https://qiita.com/maka2025/private/cfb6db137693e770d47d

https://qiita.com/maka2025/private/0d7829306185ee1b3ab2

2.Powershell スクリプトのダウンロード
MS Learnを参考に進める。
https://learn.microsoft.com/ja-jp/entra/identity/app-provisioning/inbound-provisioning-api-powershell#download-the-powershell-script

まず、以下の GitHub からダウンロードする。
https://github.com/AzureAD/entra-id-inbound-provisioning
![github_download.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/e8ad51db-4826-43b9-99ad-7fa01e99c7e8.jpeg)

ダウンロードしたデータのディレクトリ構成は MS Learn を参照ください。
とりあえず、プロビジョニング用のサンプルデータは以下にあります。
```
# ダウンロードフォルダ
\entra-id-inbound-provisioning-main\entra-id-inbound-provisioning-main\PowerShell\CSV2SCIM\Samples
```

3.Powershellを起動しコマンドを実行する
リモート署名済みのスクリプトを実行し有効にする
```
set-executionpolicy remotesigned
```
前提条件モジュールをインストールする
```
Install-Module -Name Microsoft.Graph.Applications,Microsoft.Graph.Reports
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/25473cc3-3163-4c0a-86ea-137ef8054bfa.png)

4.一括要求ペイロードを生成する
Powershell で GitHub からダウンロードしたファイルの SRC ディレクトリに移動する
```
# ダウンロードフォルダ
\entra-id-inbound-provisioning-main\PowerShell\CSV2SCIM\src\
```
下記コマンドを実行し、AttributeMapping 変数を初期化する
```
$AttributeMapping = Import-PowerShellDataFile '..\Samples\AttributeMapping.psd1'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/f1258d2f-16ed-4dae-89b5-eb878525f4ec.png)

下記コマンドを実行し、AttributeMapping ファイルに有効な SCIM スキーマ属性があるか検証する
検証に成功すると True が返ってくる
```
.\CSV2SCIM.ps1 -Path '..\Samples\csv-with-2-records.csv' -AttributeMapping $AttributeMapping -ValidateAttributeMapping
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/67286928-c4bb-409b-916f-bee399422de6.png)

コマンドを実行してエラーが出る場合は、ブロックを解除する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/00532af4-dfe7-4264-a865-213b9dd2e7c9.png)


5.CSVの2つのレコードを Json ファイルに変換します
```
.\CSV2SCIM.ps1 -Path '..\Samples\csv-with-2-records.csv' -AttributeMapping $AttributeMapping > BulkRequestPayload.json
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/a312881f-135d-4d3a-9002-c9836db13a31.png)

下記のようにファイルが生成されます
※ファイル場所：entra-id-inbound-provisioning-main\PowerShell\CSV2SCIM\src
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/50b7bc24-035b-451a-b3fa-02382a019a70.png)

5.ユーザーをAPIにアップロードする
下記にアクセスする
https://aka.ms/ge

Global Administrator ロールを持つユーザーでログインする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/922f8407-4697-446e-a747-a9f9b62ff1e8.png)

API エンドポイントのプロビジョニングの値をコピーする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/4fcc818d-f5a0-467f-a3d7-61324c90b917.png)

HTTPの要求を POST に設定し、先程コピーした値を貼り付ける
Key に Content-Type
Valu に application/scim+json を入れ追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/e6e222a9-6ee2-45fe-91c4-1bfc90e7a777.png)

Request Body に先程 CSV から JSON に変換した BulkRequestPayload.json の中身か、以下の SCIM Enterprise ユーザースキーマを使用した一括要求を張り付け、クエリを実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/a8b1cd61-8151-48f2-8446-8f248526682f.png)


<details><summary>SCIM Enterprise ユーザースキーマを使用した一括要求</summary>

```
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
    "Operations": [
    {
        "method": "POST",
        "bulkId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
        "path": "/Users",
        "data": {
            "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
            "externalId": "701984",
            "userName": "bjensen@example.com",
            "name": {
                "formatted": "Ms. Barbara J Jensen, III",
                "familyName": "Jensen",
                "givenName": "Barbara",
                "middleName": "Jane",
                "honorificPrefix": "Ms.",
                "honorificSuffix": "III"
            },
            "displayName": "Babs Jensen",
            "nickName": "Babs",
            "emails": [
            {
              "value": "bjensen@example.com",
              "type": "work",
              "primary": true
            }
            ],
            "addresses": [
            {
              "type": "work",
              "streetAddress": "100 Universal City Plaza",
              "locality": "Hollywood",
              "region": "CA",
              "postalCode": "91608",
              "country": "USA",
              "formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
              "primary": true
            }
            ],
            "phoneNumbers": [
            {
              "value": "555-555-5555",
              "type": "work"
            }
            ],
            "userType": "Employee",
            "title": "Tour Guide",
            "preferredLanguage": "en-US",
            "locale": "en-US",
            "timezone": "America/Los_Angeles",
            "active":true,
            "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
                 "employeeNumber": "701984",
                 "costCenter": "4130",
                 "organization": "Universal Studios",
                 "division": "Theme Park",
                 "department": "Tour Operations",
                 "manager": {
                     "value": "89607",
                     "displayName": "John Smith"
                 }
            }
        }
    },
    {
        "method": "POST",
        "bulkId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
        "path": "/Users",
        "data": {
            "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"],
            "externalId": "701985",
            "userName": "Kjensen@example.com",
            "name": {
                "formatted": "Ms. Kathy J Jensen, III",
                "familyName": "Jensen",
                "givenName": "Kathy",
                "middleName": "Jane",
                "honorificPrefix": "Ms.",
                "honorificSuffix": "III"
            },
            "displayName": "Kathy Jensen",
            "nickName": "Kathy",
            "emails": [
            {
              "value": "kjensen@example.com",
              "type": "work",
              "primary": true
            }
            ],
            "addresses": [
            {
              "type": "work",
              "streetAddress": "100 Oracle City Plaza",
              "locality": "Hollywood",
              "region": "CA",
              "postalCode": "91618",
              "country": "USA",
              "formatted": "100 Oracle City Plaza\nHollywood, CA 91618 USA",
              "primary": true
            }
            ],
            "phoneNumbers": [
            {
              "value": "555-555-5545",
              "type": "work"
            }
            ],
            "userType": "Employee",
            "title": "Tour Lead",
            "preferredLanguage": "en-US",
            "locale": "en-US",
            "timezone": "America/Los_Angeles",
            "active":true,
            "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
                 "employeeNumber": "701985",
                 "costCenter": "4130",
                 "organization": "Universal Studios",
                 "division": "Theme Park",
                 "department": "Tour Operations",
                 "manager": {
                     "value": "701984",
                     "displayName": "Barbara Jensen"
                 }
            }
        }
    }
],
    "failOnErrors": null
}
```
</details>

Entra ID 管理センター > エンタープライズアプリ > テスト用に登録したアプリ > プロビジョニング
登録したユーザー数が表示される
プロビジョニングログの表示から登録ユーザーが確認できる
※ プロビジョニングログにすぐ反映されない場合があります。Entra ID のユーザーからプロビジョニングされたユーザーを検索するのが確実です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016871/eaeaad68-4be1-4291-abfd-85fed3d21210.png)


6.まとめ
設定さえ終われば以下の流れでユーザーは作成できました。
CSVでユーザーデータを生成
JSONファイルへ変換
Graph ExplorerにJSONの中身貼り付け
クエリ実行


＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。