SaaS

【Microsoft Entra】ネストされたグループのメンバーを一覧で取得する

はじめに

こんにちは。通勤ラッシュに慣れてきたすかんくです。
運用支援チームの2025年Advent Calendar、15日目になります。

Cloudnative IRS Advent Calendar 2025 – Adventar

今回はEntra ID上でネストされているユーザーやデバイスの一覧を手っ取り早く取得する方法についてご紹介します。

注意

2025年12月時点での情報です。 最新の情報については各サービスの公式ドキュメントなどをご確認ください。

背景

Entra ID上でネストされたグループのユニークなメンバーを取得しようと思ったら、通常だとこんな手順になるかと思います。

  1. グループAのメンバー一覧を取得
  2. グループBのメンバー一覧を取得
  3. 各一覧らを結合して重複排除処理を掛ける

これが手間だなと思いながら管理画面を眺めていたら、[すべてのメンバー] というタブがあるではないですか。

見た限り、ネストされているグループに所属するメンバーをすべて展開してくれる機能のようだったので、これはそれ用のAPIがあるなということで本内容に至ります。

管理画面上でGraph APIを調査する

記事の本題とは横道にそれますが、M365は管理画面上の内容も基本的にはAPIドリブンで表示・管理されています。ですので、管理画面上で叩かれているAPIを知ることが出来れば、スクリプトに落とし込んだり自動化したりする作業が非常に楽となります。

  • 今どき生成AIに聞けば解決することも多くあるかと思いますが、やはり正確かつ最新の情報を取得するのであればこのような手段は必要だと考えます
  • 今回はGraph X-RayというChrome拡張を利用していますが、各々方法についてはお任せいたします

上記画像からは、GET /groups/<group id>/transitiveMembersというエンドポイントを叩いていることが分かります。また、今回利用したツールではそれに対応するGraph PowerShellコマンドも表示してくれるので大変便利です。

画面上の表示制限的な意味合いで top 20 がリクエストされているようなので、一覧を取得するスクリプトに落とし込む際にはこの辺りのオプションは不要だな、といったあたりは付けておきましょう。

一覧を出力するスクリプト

ということで本題です。以下が特定グループのメンバー(ユーザー/デバイス)の一覧を出力するスクリプトとなります。

  • ポイントはGet-MgBetaGroupTransitiveMemberAsUser-All を指定している箇所ですが、弊社環境では3万件弱のオブジェクト数でも問題無く動作することを確認しています
# 設定
Write-Host "対象グループ:xxxxx" -ForegroundColor Cyan
$GroupId = "<group id>"
$OutputPath = ".\GroupMembers_Combined.csv"

# 接続
Connect-MgGraph

# 結果を格納するリストを作成
$Results = [System.Collections.Generic.List[PSCustomObject]]::new()

# 1. ユーザーの取得と処理
Write-Host "ユーザー情報を取得中..." -ForegroundColor Cyan
try {
    $users = Get-MgBetaGroupTransitiveMemberAsUser -GroupId $GroupId -All -ErrorAction Stop
    foreach ($user in $users) {
        # ユーザー用のオブジェクトを作成(デバイス固有項目は $null)
        $obj = [PSCustomObject]@{
            '種別'       = 'user'
            '表示名'     = $user.DisplayName
            'ID'        = $user.Id
            'UPN'       = $user.UserPrincipalName
            '所有者'     = $null
            '信頼種別'   = $null
            '登録方式'   = $null
        }
        $Results.Add($obj)
    }
}
catch {
    Write-Warning "ユーザーの取得に失敗しました: $_"
}

# 2. デバイスの取得と処理
Write-Host "デバイス情報を取得中..." -ForegroundColor Cyan
try {
    $devices = Get-MgBetaGroupTransitiveMemberAsDevice -GroupId $GroupId -All -ErrorAction Stop
    foreach ($device in $devices) {
        # デバイス用のオブジェクトを作成(ユーザー固有項目は $null)
        $obj = [PSCustomObject]@{
            '種別'       = 'device'
            '表示名'     = $device.DisplayName
            'ID'        = $device.Id
            'UPN'       = $null
            '所有者'     = $device.DeviceOwnership
            '信頼種別'   = $device.TrustType
            '登録方式'   = $device.EnrollmentType
        }
        $Results.Add($obj)
    }
}
catch {
    Write-Warning "デバイスの取得に失敗しました: $_"
}

# 3. CSVへの出力
if ($Results.Count -gt 0) {
    # 日本語文字化け防止のため Encoding UTF8 を指定
    $Results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8BOM
    Write-Host "CSV出力が完了しました: $OutputPath" -ForegroundColor Green
} else {
    Write-Warning "出力対象のデータがありませんでした。"
}

出力項目は以下の通りです。(必要な項目が不足している場合は好きに改変してご利用ください)

項目ユーザーデバイス
種別“user”“device”
表示名
ID
UPNnull
所有者null
信頼種別null
登録方式null

補足

Graph PowerShellモジュールのバージョンが低い場合、スクリプト内のコマンドにバグがあり、稀にエラーが発生することがあります。その際は、全モジュールを一度アンインストールして再インストールすることで解消されることを確認しています。

Get-MgBetaGroupTransitiveMemberAsUser : 1 つ以上のエラーが発生しました。
発生場所 行:3 文字:1
+ $users = Get-MgBetaGroupTransitiveMemberAsUser  -GroupId 'xxx ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-MgBetaGroup...mberAsUser_List], AggregateException
    + FullyQualifiedErrorId : System.AggregateException,Microsoft.Graph.Beta.PowerShell.Cmdlets.GetMgBetaGroupTransiti
   veMemberAsUser_List

おわりに

今回はEntra IDのネストされたグループメンバーを効率的に取得する方法についてご紹介しました。
管理画面の裏側で動いているAPIを調べることで、手作業では面倒な処理も簡単にスクリプト化できることがお分かりいただけたかと思います。皆様の業務効率化の一助となれば幸いです。ではまた!

すかんく

運用支援チームのすかんくです