Microsoft Entra ID(旧Azure AD)の動的グループは、ユーザー属性からメンバーを自動的に増減できる便利機能です。一方で「ディレクトリ拡張属性を複数値(配列)で持たせ、-any/-allで含有判定したい」というケースは、ルールが期待どおりに動かず詰まりがちです。本記事では“なぜ無理なのか”を整理し、実務で使える回避策を具体例つきで解説します。
起きていること:拡張属性が“配列”として扱われず、-any/-allが効かない
前提として、Microsoft Entra ID のディレクトリ拡張属性(例:extension_xxxx_TestCollection)に、複数値の文字列コレクションを入れて運用している状況を想定します。
例(ユーザー属性のイメージ):
extension_xxxx_TestCollection = ["sign2", "sign1"]
そして動的グループのメンバーシップ ルールで、次のような含有判定を書きたい。
(user.extension_xxxx_TestCollection -any (_ -eq "sign1"))
しかし実際は、動的グループ側ではこの拡張属性が単一値の文字列のように扱われてしまう(あるいは配列として評価されない)ため、-any/-allによる判定ができません。クラウド完結(Entra Connectなし)でも同様です。
結論:動的グループ ルールでは「複数値の拡張属性」はサポート外
結論から言うと、Entra ID の動的グループ ルールは、拡張属性・カスタム拡張プロパティを“文字列プロパティ”として扱う前提であり、複数値(multi-value)の拡張プロパティは動的ルールでサポートされません。そのため、-any/-allで評価することはできません。
Microsoft Learn の動的メンバーシップ ルール解説では、拡張属性/カスタム拡張プロパティはルールで使える一方で、multi-value の拡張プロパティは非対応である旨が明記されています。
なぜ混乱するのか:同期やGraphでは“複数値”が見えるのに、動的ルールは別エンジンで評価している
この問題がややこしいのは、周辺機能では「複数値」が成立しているように見えることがあるからです。
- ディレクトリ拡張(Directory extensions)は、仕組みとしては単一値・複数値どちらも存在し得る(とくにオンプレADからの同期ではマルチバリューも候補になり得る)。
- ただし Microsoft Learn でも「すべての機能が multi-valued 拡張属性をサポートするわけではない」と注意書きがあり、使いたい機能のドキュメントで確認せよ、とされています。
- 動的グループの評価エンジンは、拡張属性を“配列として走査する”実装になっていないため、ルール言語として
-any/-allが書けても、その対象にできない(または期待どおりに評価されない)。
実際に、同様の内容が Microsoft Q&A でも「multi-value extension properties は dynamic membership rules でサポートされない」と回答されています。
-any/-all自体がダメなわけではない:使える“多値プロパティ”と、使えない“拡張属性”がある
誤解されがちですが、動的グループ ルールで-anyが全面的に禁止されているわけではありません。例えば Microsoft Learn の手順解説でも、proxyAddressesのような複数値プロパティに対して-anyを使う例が示されています。
つまりポイントはこうです。
| 項目 | 動的グループ ルールでの扱い | 現場での見え方 | 結果 |
|---|---|---|---|
標準の多値属性(例:proxyAddresses) | 多値として評価できるケースがある | -anyで条件を書ける | 期待どおり動くことが多い |
拡張属性(extensionAttribute1-15) | ルールでは“文字列プロパティ”として利用 | 単一値前提で比較 | 多値運用はできない |
カスタム拡張プロパティ(extension_{GUID}_{name}) | ルールでは“文字列プロパティ”として利用 | 配列を入れても配列として扱われない | -any/-all |
拡張属性・カスタム拡張プロパティは「使える」と書かれていても、それは“単一値の文字列として使える”という意味合いです。
回避策:要件に合わせて「単一値化」か「外部自動化」に寄せる
では、["sign2","sign1"]のような配列をどう扱えばいいのか。現実的な選択肢は大きく次の2系統です。
- 設計を“単一値で判定できる形”に寄せる(動的グループを活かす)
- 動的グループをやめ、Graph等で静的グループを自動更新する(配列運用を維持する)
それぞれのメリット・デメリットを先に俯瞰します。
| 方式 | メリット | デメリット | 向いているケース |
|---|---|---|---|
| フラグ属性に分割(単一値×複数) | 動的グループだけで完結/判定が明快 | 属性数が増える/設計変更が必要 | タグ種類が限定的、運用をシンプルにしたい |
| タグを1つの文字列へ正規化(区切り文字) | 属性を増やさず単一値で判定可能 | 誤一致対策が必須/表記揺れに弱い | タグが増減する、ただし運用で正規化できる |
| 静的グループを自動更新(Graph + 定期実行) | 配列のまま柔軟に判定可能/複雑条件も実装可 | 運用部品が増える/権限・監視が必要 | タグが多い、複合条件が多い、将来拡張したい |
回避策:フラグ属性に分割して動的ルールで判定する
もっとも堅いのは、“配列で持つのをやめる”ことです。具体的には「sign1を持つか?」を単一値で表現できるようにします。
例:拡張属性を次のように分割
extension_xxxx_hasSign1:"true"/"false"extension_xxxx_hasSign2:"true"/"false"
動的ルールは単純化できます。
(user.extension_xxxx_hasSign1 -eq "true")
「Booleanで持ちたい」と思うかもしれませんが、動的グループの拡張属性は基本的に“文字列として扱う前提”で設計しておくとハマりにくいです("true"/"false"のように表現を固定)。
フラグ方式が強い理由
- ルールが読みやすい(監査・引き継ぎが楽)
- 誤一致が起きない(
sign1とsign10問題が発生しない) - 管理者がポータルでルールを見ても意図が分かる
弱点:タグ種類が増えると属性が増える
タグが数十〜数百に増える見込みがあるなら、フラグ分割は現実的でなくなります。その場合は次の「正規化して1つの文字列に詰める」か、「自動化で静的グループ更新」を検討します。
回避策:区切り文字で1つの文字列に正規化し、部分一致で判定する(応急・条件付き)
拡張属性が単一値文字列としてしか扱えないなら、最初から単一の文字列として保存し、ルール側は文字列検索で判定する、という発想です。
ただし、ここで最大の事故要因が誤一致です。例えば次の保存だと危険です。
"sign1,sign2"
なぜなら -contains "sign1" が sign10 にもマッチする等、事故が起きます。そこで実務では、次のようにトークンの両側を区切り文字で囲む“正規化”が定番です。
推奨例(両側ガード方式):
"|sign1||sign2|"
ルール例:
(user.extension_xxxx_TestCollection -contains "|sign1|")
正規化ルール(最低限これだけは守る)
| 項目 | 推奨 | 理由 |
|---|---|---|
| 区切り文字 | |など、タグに含めない文字を採用 | タグ自体に区切り文字が入ると判定が壊れる |
| 前後ガード | |tag|の形に統一 | tagとtag10の誤一致を防ぐ |
| 大小文字 | 小文字に統一 | 表記揺れ・運用ミスを減らす |
| 空白 | 入れない(トリムして保存) | 検索時の意図しない不一致を防ぐ |
この方式は「早く直したい」「属性を増やせない」時の現実解ですが、運用ルールが崩れた瞬間に精度が落ちます。長期運用なら、次の自動化方式のほうが安全なことも多いです。
回避策:動的グループを諦めて、Graphで“静的グループ”を定期更新する
どうしても配列として持ちたい、または「配列+複雑条件(AND/OR/例外)」をやりたい場合は、静的グループを自動化で更新するのが最も柔軟です。
概念はシンプルです。
- ユーザーの
extension_xxxx_TestCollection(配列)を Graph で取得 - 配列に
sign1が含まれるユーザーを抽出 - 対象ユーザーを静的グループへ追加/不要ユーザーは削除
- これを定期実行(例:15分、1時間、1日)
実装手段の比較(迷ったらここから)
| 手段 | 向き | 強み | 注意点 |
|---|---|---|---|
| Azure Functions(Timer) | 中〜大規模、拡張しやすさ重視 | コードで自由に条件を組める/Git管理しやすい | 監視・例外処理・資格情報管理が必要 |
| Logic Apps | 運用チームがコードを避けたい | GUI中心/コネクタで組みやすい | 複雑条件が増えると管理が重くなる |
| Azure Automation Runbook | PowerShell中心の運用 | 馴染みやすい/スケジュールしやすい | モジュール管理や実行環境差分に注意 |
サンプル:Microsoft Graph PowerShellで“配列タグ”を見てグループを更新する(概要)
ここでは「配列に sign1 が含まれるユーザーを、特定のグループに入れる」最小構成のイメージを示します。実運用では、差分更新・例外処理・スロットリング対策などを追加してください。
# 前提:
# - 更新対象グループ:$groupId
# - 拡張属性:extension_xxxx_TestCollection(配列想定)
# - 必要権限:読み取り(ユーザー)、書き込み(グループメンバー)
# ※運用では最小権限・監査ログ・証明書/Managed Identity等を検討
Connect-MgGraph -Scopes "User.Read.All","GroupMember.ReadWrite.All"
$groupId = "00000000-0000-0000-0000-000000000000"
$extName = "extension_xxxx_TestCollection"
# ユーザー取得(必要な属性だけ取得するのがコツ)
$users = Get-MgUser -All -Property "id,displayName,$extName" -ConsistencyLevel eventual
foreach ($u in $users) {
# 拡張属性は AdditionalProperties 側に入るケースが多い
$tags = $u.AdditionalProperties[$extName]
$has = $false
if ($tags -is [System.Collections.IEnumerable]) {
$has = $tags -contains "sign1"
}
if ($has) {
# グループに追加(既に入っている場合の処理は省略)
New-MgGroupMemberByRef -GroupId $groupId -BodyParameter @{
"@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($u.Id)"
}
} else {
# グループから削除(既にいない場合の処理は省略)
# Remove-MgGroupMemberByRef -GroupId $groupId -DirectoryObjectId $u.Id
}
}
上記は考え方を示すための骨格です。実務での“落とし穴”は次の章でまとめます。
自動化方式の落とし穴(ここを押さえると運用が安定する)
- 差分更新:毎回全ユーザーを走査すると重いので、可能なら変更ユーザーだけ処理する(例:Graphのdeltaクエリ活用)
- 冪等性:同じユーザーを何度追加しても壊れない、削除しても壊れない作りにする
- スロットリング:Graphは大量更新で制限に当たり得るため、バッチ化やリトライを入れる
- 最小権限:アプリ権限を安易に盛らない(監査対象になりやすい)
- 監視:実行結果(追加件数/削除件数/エラー)をログに残し、通知ルートを用意する
「じゃあ custom security attributes を使えば?」への答え:動的グループでは使えない
最近のEntra IDでは custom security attributes(カスタム セキュリティ属性)も選択肢に入りますが、少なくとも動的グループのルール条件としてはサポートされません。そのため「多値で持てる属性に置き換えよう」と考えても、動的ルール目的では解決しない点に注意が必要です。
補足:拡張の種類は似ているが、動的ルールで使える範囲は限られる
“拡張”という言葉が多すぎて混乱しやすいので、動的グループ目線でざっくり整理します。
| 種類 | 例 | 動的グループでの扱い | コメント |
|---|---|---|---|
| 拡張属性(Extension attributes 1-15) | extensionAttribute1 など | 文字列として利用可能 | 単一値前提。 |
| カスタム拡張プロパティ(Directory / Entra extension properties) | extension_{GUID}_{name} | 文字列として利用可能 | 単一値前提。multi-valueは非対応。 |
| Microsoft Graph schema extensions | schemaExtensions | 動的ルールでは未対応とされることがある | 用途が似ていても同列に扱えない。 |
| custom security attributes | customSecurityAttributes | 動的ルールでは非対応 | ABAC等では有用だが用途が違う。 |
つまり今回の課題は「配列が入る/入らない」の話だけではなく、“動的グループの評価エンジンが、どの属性をどんな型として解釈するか”が本質です。
スレッドで見かける「ドキュメントに明記がない」問題について
現場では「ドキュメントに“複数値拡張属性は使えない”と明記されていないのでは?」という議論が起きることがあります。実際、コミュニティ回答や古い情報が混ざると判断が難しくなります。
ただ、Microsoft Learn の動的メンバーシップ ルール解説では、拡張属性/カスタム拡張プロパティの項目においてmulti-value extension properties は動的ルールでサポートされない旨が示されています。したがって、Q&Aでの結論(非対応)を前提に設計を組み直すのが安全です。
トラブルシューティング:まず“ルールが正しく評価される前提”を整える
多値が原因で詰まっている場合でも、ついでに動的グループ運用でよくある詰まりポイントを押さえておくと、復旧が早くなります。
ルールを検証して「想定ユーザーがヒットするか」を先に確認する
Microsoft Entra ID には動的グループのルール検証(Validate rules)機能があり、サンプルユーザーに対して条件を満たす/満たさないを確認できます。本番反映の前に必ず検証するのが安全です。
処理は即時ではない(更新反映にタイムラグがある)
動的グループは属性変更のたびに評価されますが、評価・反映は非同期で進みます。グループのステータス(Evaluating / Processing / Update complete / Processing error など)を確認して、処理中なのか、エラーなのかを切り分けてください。
複雑ルールはルールビルダーでは表現しきれないことがある
ルールビルダーは便利ですが、複雑な式(例:-anyを含む高度な式)はテキストボックスで入力が推奨されるケースがあります。今回のような式も、入力自体はできても“評価対象の属性が非対応”だと結果が出ません。
現場向けの最終提案:迷ったらこの判断基準で決める
最後に、実務での意思決定が早くなるように「どう選ぶか」を基準化しておきます。
- タグ種類が少ない(〜20程度):フラグ分割が最も堅い。運用が簡単で事故が少ない。
- タグ種類が多い・増減が頻繁:静的グループ自動更新が柔軟。差分更新・監視までセットで設計する。
- とにかく早く暫定対処が必要:区切り文字で単一文字列へ正規化。ただし正規化ルールを崩さない運用が必須。
今回のポイントは「動的グループで multi-valued の拡張属性を配列として評価することはできない」という前提を受け入れ、設計(データの持ち方)か方式(自動化)を変えることです。拡張属性をどう持つかは、後からの移行が意外と大変なので、将来のタグ増加や運用負荷まで含めて選ぶのがおすすめです。

コメント