セイテクエンジニアのブログ かつて山市良と呼ばれたおじさんのブログ vol.58 はじめてのMicrosoft Graph|Azure&Entra IDスクリプト大作戦(5)
2024年11月07日配信
執筆者:山内 和朗
これまで、Azure PowerShellやAzure REST APIでAzureのリソース情報を取得するスクリプトに挑戦してきましたが、今回はMicrosoft Entra IDからのリソース情報の取得に挑戦します。
Microsoft Entra IDのリソース情報の取得には、「Microsoft Graph」を使用します。Microsoft Graphは、Microsoft 365サービス、Enterprise Mobility+Securityサービス、Microsoft Intune、Microsoft Dynamics Business Centralサービスといった、Microsoftクラウドサービスのデータにアクセス(REST APIやクライアントライブラリ)を提供するものです。これには、Microsoft Entra IDも含まれます(Microsoft Entraサービス群は、Enterprise Mobility+Securityサービスの一部です)。
Microsoft Graph の概要|Microsoft Graph(Microsoft Learn)
Microsoft 365はMicrosoft Entra ID(旧称、Azure Active Directory、Azure AD)をディレクトリサービスとして利用しています。Microsoft 365がまだOffice 365と呼ばれていた頃、Office 365サービスを導入すると、Azureサブスクリプションが無くても、Azure Portalの「Azure Active Directory」ブレード(現在の「Microsoft Entra ID」ブレード)に限定されたアクセスが可能でした。そのため、Azure ADはAzureのサービスの一部と認識していた人は多いと思います。しかし現在、Azure ADはMicrosoft Entra IDとなり、Microsoft Entraサービス群の一部となりました。現在でも、Microsoft 365とAzureサブスクリプションの両方のサービスを利用している場合は、同じユーザー(ID)に紐づいているケースが多いと思いますが、Microsoft Entra IDはAzureとは別のサービスと考えを切り替えたほうが良いと思います。
以前、Azure ADやOffice 365へのアクセスやディレクトリ同期には、MSOnline(MSOL)やAzure PowerShellを利用していましたが、これらは2023年3月31日に廃止されました。例えばAzure PowerShellのGet-AzADUserコマンドレットなど、現在でも動作するものもありますが、今後、予告なく使用できなくなるそうです。MSOnline(MSOL)やAzure PowerShellのコマンドレットの機能は、「Microsoft Graph PowerShell」(Microsoft Graph PowerShell SDK、v1.xは2020年9月に、v2.xは2023年7月に正式リリース)および「Microsoft Graph CLI」(2023年11月に正式リリース)に置き換えられました。
MSOnline / AzureAD PowerShell から Graph PowerShell SDK への移行について 1_概要|Japan Azure Identity Support Blog
Azureでは、ユーザー(ユーザープリンシパル)やサービスプリンシパルに「ロール」を割り当てることで、AzureポータルやAzure PowerShell、Azure CLI、Azure REST APIへのアクセス権限を付与することができました。これに対して、Microsoft Graphを使用したアクセスには、「管理者の同意(Consent)」が必要という特徴があります。
例えば、Microsoft 365のユーザー(Microsoft Entra ID)の一覧を取得するGet-MgUserコマンドレットを実行するとしましょう。その場合、次に示すように最初にConnect-MgGraphコマンドレット(Azure PowerShellのConnect-AzAccountコマンドレットに相当)を実行してMicrosoft Graphのサービスに接続する必要があります。Connect-MgGraphコマンドレットでは、-ScopesパラメーターにAPIのアクセス許可「User.Read.All(またはUser.ReadBasic.All)」を要求する必要があります。
Connect-MgGraph -Scopes "User.Read.All" Get-MgUser -All DisConnect-MgGraph |
Connect-MgGraphコマンドレットはWebベースのサインイン画面を表示するので、Microsoft 365(Microsoft Entra ID)のユーザーの資格情報でサインインします。この時、多要素認証(MFA≪Multi-Factor Authentication≫)が求められた場合は、スマートフォンの「Authenticator」アプリや電話で認証を完了する必要があります。その後、「要求されているアクセス許可(Permissions requested)」が表示されるので、管理者の同意が必要なアクセス許可(「User.Read.All」など)を要求する場合は「組織の代理として同意する(Consent on behalf of your organization)」をチェックして、「承諾(Accept)」をクリックします(画面1)。
画面1 グローバル管理者であるユーザーでサインインし、要求されているアクセス許可に「同意」する
管理者による同意を行えるのは、管理者(グローバル管理者など)権限を持つユーザーでサインインした場合に限られます。管理者による同意が必要でないアクセス許可(「User.ReadBasic.All」など)の場合は、「組織の代理として同意する(Consent on behalf of your organization)」のチェックなしで「承諾」できます。なお、管理者でない一般ユーザーでサインインして「User.Read.All」を要求した場合、「管理者の承認が必要(Need admin approval)」と表示され、管理者アカウントによるサインインが要求されます。
Microsoft Graphサービスに接続できたら、そのセッション内で(Disconnect-MgGraphで切断するまで)、Microsoft Graph Powershellの各種コマンドレット(Get-MgUserなど)を実行できるようになります(画面2)。
画面2 Get-MgUserコマンドレットにより、ユーザーの一覧を取得できた
なお、Azureのときと同様に、最終的な目的はREST APIによるアクセスであるため、Microsoft Graph PowerShellのインストール方法については説明しません。詳しくは、以下のドキュメントを参照してください。
Install the Microsoft Graph PowerShell SDK|Microsoft Graph(Microsoft Learn)
Microsoftは、Microsoft Graph REST APIについて学習できる開発者ツールとして「Graph Explorer」サービスを公開しています。
Graph Explorer|Microsoft Graph(Microsoft Developer)
Graph Explorerにアクセスすると、初期状態でサンプルとして提供されている「Sample」テナントに接続され、「管理者による同意」“なし”でMicrosoft Graph REST APIに対してHTTP要求(GETやPOSTなど)を送信し、応答を取得することができます。ページ右上のユーザーのアイコン(Sign in)をクリックしてMicrosoft 365(Microsoft Entra ID)のユーザーの資格情報でサインインすると、自分のテナントに接続してAPIを試すことができます。
一般ユーザーであっても、「はじめに|[GET]自分のプロファイル」(GET https://graph.microsoft.com/v1.0/me)など、自分のリソース情報へのアクセスは可能です。これは、各ユーザーには既定で「User.Read」など自分のリソース情報へのアクセス許可が同意なしで付与されているからです(画面3)。
画面3 ユーザーの役割に関係なく、自分のリソース情報にアクセスできるのは、「User.Read」アクセス許可が既定で(同意なしで)付与されているため
一方、グローバル管理者であるユーザーでサインインしたとしても、アクセスできるリソース情報は自分のものに限定されます。例えば、「ユーザー|[GET]組織内のすべてのユーザー」(GET https://graph.microsoft.com/v1.0/users)を実行しても、「Frobiden - 403 ・・・ Either the signed-in user does not have sufficient privileges, or you need to concent to one of the permissions on the Mobidy permissions tab」というエラーが表示されます。
サインイン中のユーザーが管理者であれば、「Modify permissions」タブ(サインイン中のユーザーのアイコンをクリックして「Concent to permissions」)で必要なアクセス許可の「同意(Concent)」を要求することができます。アクセス許可の同意を要求すると、Microsoft Graph PowerShellのときと同じ「要求されているアクセス許可(Permissions requested)」が表示されるので、「承諾(Accept)」をクリックします(画面4)。これで、目的のAPIからリソース情報を取得できるようになります。例えば、「ユーザー|[GET]組織内のすべてのユーザー」には、「User.ReadBasic.All」または「User.Read.All」のアクセス許可が必要です。
どのような操作にどのようなアクセス許可が必要なのかについては、以下のドキュメントから入手できます。管理者による同意が必要かどうかは、以下のドキュメントの「AdminConsentRequired:はい/いいえ」で判断できますが、Graph Explorerの「Modify permissions」タブの「Need admin concent required」列で確認することもできます。
Microsoft Graph のアクセス許可のリファレンス|Microsoft Graph(Microsoft Learn)
画面4 「ユーザー|[GET]組織内のすべてのユーザー」の実行に必要な「User.Read.All」アクセス許可を要求する。ただし、このアクセス許可を要求できるのは管理者(グローバル管理者など)だけ
Microsoft Graphは今回が初体験だったのですが、こうしてブログ記事にまとめると、頭が整理され、ずいぶんと理解が深まったような気がします。実はこの私、管理者による同意が必要がないのにアクセス許可にも「組織の代理として同意する(Consent on behalf of your organization)」をチェックしていました。
次回は、Microsoft Graph REST APIに直接アクセスして、例えば、Microsoft 365(Microsoft Entra ID)のユーザーの一覧を取得する操作を自動化を想定してスクリプト化してみたいと思います。今回の方法はいずれも対話が必要でした。Azureの時と同様に、今回もサービスプリンシパルを使用することになるはずです。
なお、前回まで使用していたAzureサブスクリプションとそれに紐づいたMicrosoft Entra IDのユーザーは、今回は使用していません。前回までのユーザーはAzureサブスクリプションの管理者でしたが、Microsoft Entra IDでは一般ユーザーだったからです。今回は、管理者による同意を可能にするために、評価用のMicrosoft 365サブスクリプション(Azureサブスクリプションなし)を用意して使用しました。