Microsoft Purview の保持ポリシー(Retention Compliance Policy)を PowerShell で点検すると、UI で Exchange をオフにしているのに Get-RetentionCompliancePolicy の結果だけでは判断できず「反映されていない?」と感じることがあります。原因はコマンドの既定出力が“概要”である点にあり、正しい見方を知ると一気に解決します。
起きていること:UI と PowerShell の見え方がズレる
保持ポリシーの運用を自動化していると、次のような場面に出会いがちです。
- Microsoft Purview のポータル(Data Lifecycle Management など)では「Exchange の場所:オフ」になっている
- ところが PowerShell で
Get-RetentionCompliancePolicyを実行しても、Exchange の有効/無効を示すような分かりやすい値が出ない ExchangeLocationなどの Location 系プロパティが{}に見えたり、そもそも表示に出てこなかったりして混乱する
結論から言うと、“場所設定が反映されていない”のではなく、“見ている出力がサマリー表示で詳細が省略されている”ケースが大半です。
原因:Get-RetentionCompliancePolicy の既定出力は「概要」
Get-RetentionCompliancePolicy は、オプションを付けない既定の状態だとサマリー(概要)を返します。Microsoft Learn の説明でも、既定表示ではポリシー名や Enabled などの概要項目が中心であることが明示されています。
さらに重要なのが、-DistributionDetail を付けない場合、DistributionStatus と *Location プロパティの値は不正確になり得る、という注意書きです。つまり、Location を頼りに「Exchange がオン/オフ」と断定すると誤判定になりやすい、ということです。
「Workload 列がいつも同じ」に見えるのも仕様
既定出力の Workload についても、現場では混乱ポイントになります。Microsoft Learn では、Workload は“現在は全ワークロードを表示する(Exchange / SharePoint / OneDrive / Skype / ModernGroup など)”と説明されており、実際にどのワークロードに適用されているかを示すものではない旨が書かれています。
このため、「Workload が全部出ているのに Exchange をオフにしても変化しない」=「設定が効いてない」と見えてしまいますが、ここも既定表示の性格によるものです。
解決策:-DistributionDetail を付けて“正しい Location”を取得する
場所(Location)の有効/無効や対象範囲を正しく見たいなら、実質的に-DistributionDetail は必須です。このスイッチを付けると、DistributionResults に配布の詳細が入り、*Location プロパティも正確な値が取得できると説明されています。
まずは、最小構成で「そのポリシーの Location をまとめて確認」する例です。
Get-RetentionCompliancePolicy -Identity "My Policy Name" -DistributionDetail |
Format-List Name, Enabled, Mode,
ExchangeLocation, ExchangeLocationException,
SharePointLocation, SharePointLocationException,
OneDriveLocation, OneDriveLocationException,
ModernGroupLocation, ModernGroupLocationException,
TeamsChannelLocation, TeamsChannelLocationException,
TeamsChatLocation, TeamsChatLocationException,
SkypeLocation
※表示したい Location は環境(ポリシー種別)によって増減します。まずは Format-List * で一度フル表示し、実在するプロパティだけに絞ると事故が減ります。
Location プロパティの読み方
-DistributionDetail を付けたうえで、よく出会う値のパターンを整理します。
| 見え方(例) | 意味(実務的な解釈) | よくある UI 側の状態 |
|---|---|---|
ExchangeLocation = {All} | Exchange を全体対象として有効化 | Exchange の場所がオン(全体) |
ExchangeLocation = {user1, user2, ...} | Exchange を特定対象で有効化(静的スコープ) | Exchange の場所がオン(対象指定) |
ExchangeLocation = {} | Exchange の対象が存在しない(オフ/未設定) | Exchange の場所がオフ |
*LocationException = {userA, ...} | 例外(除外)として指定されている対象 | 「除外」リストに追加済み |
ポイントは、-DistributionDetail なしの {} は“正しい空”とは限らないことです。まずは必ず -DistributionDetail で取り直してから判定してください。
まずここから:Security & Compliance PowerShell に正しく接続する
Get-RetentionCompliancePolicy は、通常の Exchange Online PowerShell とは別枠のSecurity & Compliance PowerShell 側で利用するコマンドです。Microsoft Learn でも「この cmdlet は Security & Compliance PowerShell でのみ利用可能」と明記されています。
接続の流れは次の通りです(対話サインインの例)。
- Exchange Online PowerShell モジュールを読み込む
Connect-IPPSSessionで Security & Compliance PowerShell に接続する- 終わったら
Disconnect-ExchangeOnlineで切断する
# モジュールの読み込み
Import-Module ExchangeOnlineManagement
# Security & Compliance PowerShell へ接続
Connect-IPPSSession -UserPrincipalName [email protected]
# 動作確認(ここで Get-RetentionCompliancePolicy が実行できればOK)
Get-RetentionCompliancePolicy
# 切断
Disconnect-ExchangeOnline -Confirm:$false
接続手順や注意点(環境ごとの接続先 URI、PowerShell 7 の挙動など)は Microsoft Learn の「Connect to Security & Compliance PowerShell」にまとまっています。
実務で効く:ON/OFF をレポート形式に正規化するサンプル
運用で困るのは、「Location の生値」を見ても人間がすぐ判断できないことです。そこで、{All} / {} / リスト指定をざっくり正規化して、監査・棚卸しに使える形にする例を載せます。
function Get-RetentionPolicyLocationSummary {
param(
[Parameter(Mandatory)]
[string]$Identity
)
$p = Get-RetentionCompliancePolicy -Identity $Identity -DistributionDetail
function NormalizeLocation($value) {
if ($null -eq $value) { return "N/A" }
if ($value.Count -eq 0) { return "OFF/Empty" }
if ($value.Count -eq 1 -and $value[0].ToString() -eq "All") { return "ON (All)" }
return "ON (Static: $($value.Count) items)"
}
[pscustomobject]@{
Name = $p.Name
Enabled = $p.Enabled
Mode = $p.Mode
Exchange = NormalizeLocation $p.ExchangeLocation
EX_Except = ($p.ExchangeLocationException | Measure-Object).Count
SharePoint = NormalizeLocation $p.SharePointLocation
SPO_Except = ($p.SharePointLocationException | Measure-Object).Count
OneDrive = NormalizeLocation $p.OneDriveLocation
OD_Except = ($p.OneDriveLocationException | Measure-Object).Count
M365Group = NormalizeLocation $p.ModernGroupLocation
GroupExcept = ($p.ModernGroupLocationException | Measure-Object).Count
TeamsChannel = NormalizeLocation $p.TeamsChannelLocation
TeamsChat = NormalizeLocation $p.TeamsChatLocation
}
}
Get-RetentionPolicyLocationSummary -Identity "My Policy Name" | Format-List
この形にしておくと、「Exchange が ON/All なのに例外が多すぎる」「OneDrive が OFF のはずが ON になっている」などが棚卸しで一目で分かります。
対象一覧が長いときの“切れ対策”
ExchangeLocation などが大量だと、画面表示では途中で見づらくなります。実務では次のようにCSV/JSON に落として確認すると確実です。
$p = Get-RetentionCompliancePolicy -Identity "My Policy Name" -DistributionDetail
# Exchange の対象だけをテキスト化して保存(見やすい)
$p.ExchangeLocation | Out-File -FilePath ".\ExchangeLocation.txt" -Encoding utf8
# 例外も保存
$p.ExchangeLocationException | Out-File -FilePath ".\ExchangeLocationException.txt" -Encoding utf8
# 深い階層が混ざる場合は JSON(Depth を上げる)
$p | ConvertTo-Json -Depth 10 | Out-File -FilePath ".\PolicyDetail.json" -Encoding utf8
「設定は正しいのに効いていない?」を切り分ける:配布状況の確認
Location が正しく取れても、現場では次の二択で悩みます。
- ポリシーの場所設定は正しい(= 期待通りの Location が出ている)
- しかし、配布(sync/distribution)が終わっておらず、対象側に反映されていない
この切り分けに使うのが DistributionResults です。Microsoft のトラブルシューティング記事でも、ポリシーのエラー内容は -DistributionDetail を付けて DistributionResults を展開して確認する流れが示されています。
Get-RetentionCompliancePolicy -Identity "My Policy Name" -DistributionDetail |
Select-Object -ExpandProperty DistributionResults
代表的なエラーと対処の方向性
DistributionResults には、例えば以下のような状態が出ます(名称は例で、環境により複数出ます)。Microsoft Learn の解決手順では、エラー内容ごとに「場所の重複を消す」「サイト容量を確保する」「Retry する」などの具体策が案内されています。
| DistributionResults に出がちな例 | 意味のイメージ | まずやること |
|---|---|---|
MultipleInactiveRecipientsError | 指定した場所が一意に解決できない | 重複している場所指定を整理し、再配布 |
SiteOutOfQuota | 対象サイトの容量不足 | 容量を増やす/不要データ削除 → 再配布 |
PolicySyncTimeout | 同期が時間内に完了しない | 時間を置く/RetryDistribution |
ActiveDirectorySyncError | Microsoft Entra ID 同期に失敗 | 再試行(Retry)、必要ならサポート調査 |
再配布(RetryDistribution)の実行例
PowerShell 側で「再配布」を明示的にかけたい場合、Microsoft の手順でも Set-RetentionCompliancePolicy の -RetryDistribution が案内されています。
Set-RetentionCompliancePolicy -Identity "My Policy Name" -RetryDistribution
また、Set-RetentionCompliancePolicy 自体は“組織全体のフル同期を引き起こす大きな操作”であり、次の更新は配布が成功してから行うのが推奨されています。自動化では特に連続実行しない設計が安全です。
ルールを確認したい:Get-RetentionComplianceRule で保持期間・動作を読む
保持ポリシーは「どこに適用するか(Location)」と「何をするか(Rule)」がセットです。Location が正しく見えても、実際の保持期間や削除動作が期待通りかはルール側を見ないと分かりません。
ルールは Get-RetentionComplianceRule で確認します。Microsoft Learn の構文では -Policy パラメーターでポリシーに紐づくルールを絞り込めます。
Get-RetentionComplianceRule -Policy "My Policy Name" | Format-List *
よく確認する観点は次の通りです(プロパティ名は環境やルール種別で差が出るため、まず Format-List * で把握してください)。
- 保持アクション:保持のみ/削除のみ/保持後に削除
- 保持期間:日数(例:3650 日=10年)、または Unlimited
- 期限日の基準:作成日基準か、更新日基準か
- 条件:KQL(ContentMatchQuery)などで対象を絞っているか
保持アクションと保持期間を“言語化”する
ルールの編集コマンドである Set-RetentionComplianceRule のパラメーターを見ると、保持期間や保持動作がどの名前で扱われるかが分かります。たとえば、保持動作は RetentionComplianceAction、保持期間は RetentionDuration で指定し、アクションは Delete/Keep/KeepAndDelete が定義されています。
| 項目 | PowerShell(例) | 意味 |
|---|---|---|
| 保持アクション | RetentionComplianceAction = Keep | 保持のみ(削除はしない) |
| 保持アクション | RetentionComplianceAction = Delete | 削除のみ(一定期間後に削除) |
| 保持アクション | RetentionComplianceAction = KeepAndDelete | 一定期間保持し、その後削除 |
| 保持期間 | RetentionDuration = 180 | 180 日保持(単位は日) |
| 保持期間 | RetentionDuration = Unlimited | 無期限(削除しない/永続保持) |
制限と運用設計:静的スコープの上限を先に知っておく
「コマンドの制限はある?」という疑問に対して、実務で効くのは静的スコープ(手で対象を列挙する方式)の上限です。Microsoft Learn の上限ドキュメントでは、静的スコープで “特定のユーザー/グループ/サイトを含める・除外する” 場合の上限が workload 別に整理されています。
| 対象(静的スコープ) | 1ポリシーあたりの最大数 | 設計上の注意 |
|---|---|---|
| Exchange メールボックス | 1,000 | 人事異動や入退社で増減が多いなら、アダプティブ スコープも検討 |
| Microsoft 365 グループ | 500 | 部署・プロジェクトでグループが増える組織は分割設計が必要になりやすい |
| Teams チャネル メッセージ | 1,000 | 対象チームが多い場合はスコープ設計を最初に固める |
| Teams チャット メッセージ | 1,000 | ユーザー個別指定の運用は上限到達が早い |
| SharePoint サイト | 100 | 特定サイトを個別指定する設計はポリシー数が増えやすい |
| OneDrive アカウント | 100 | 個別指定が多いなら、アダプティブ スコープやルール再設計を検討 |
上限を超えそうな場合の現実解は次のどちらかです。
- ポリシーを分割して、同じ保持設定を複数ポリシーで配る(上限は“ポリシー単位”)
- アダプティブ スコープ(属性ベースの動的スコープ)を検討して、対象の増減を運用で吸収する
なお、テナント全体のポリシー数にも上限があり、Exchange/SharePoint/OneDrive のワークロード別に最大値が整理されています(例:Exchange の上限 1,800 など)。大量運用している組織では、棚卸し時に一度確認しておくと安心です。
よくある落とし穴と、早く抜けるチェックリスト
Location を見たのに UI と合わない
-DistributionDetailを付け忘れていないか(最優先)- そもそも Security & Compliance PowerShell に接続できているか(別セッションで実行していないか)
- 配布が終わっていない/エラーで止まっていないか(DistributionResults を展開)
Teams の保持ポリシーだけ一覧したい
Get-RetentionCompliancePolicy には Teams のみを返すスイッチ(-TeamsPolicyOnly)や Teams を除外するスイッチ(-ExcludeTeamsPolicy)があります。Teams 関連の棚卸しでは、ポリシー一覧が膨らむテナントほど効きます。
# Teams のみ
Get-RetentionCompliancePolicy -TeamsPolicyOnly
# Teams を除外
Get-RetentionCompliancePolicy -ExcludeTeamsPolicy
ルールがあるのに “無い”ように見える
ポリシー側で「ルール種別」まで確認したい場合、-RetentionRuleTypes スイッチが必要です。付けない場合、RetentionRuleTypes が空に見えたり HasRules が False に見えたりすることがある、と Microsoft Learn で説明されています。
Get-RetentionCompliancePolicy -RetentionRuleTypes |
Format-Table -Auto Name, RetentionRuleTypes
まとめ:場所設定が見えないときは “仕様のサマリー表示” を疑う
Get-RetentionCompliancePolicyの既定出力は概要で、Location の値は不正確になり得る- 場所(Exchange/SharePoint/OneDrive/Teams など)の ON/OFF を確認したいなら
-DistributionDetailが必須 - 配布状況やエラーは
DistributionResultsを展開して確認し、必要なら-RetryDistributionを使う - 保持期間や動作は
Get-RetentionComplianceRule -Policyでルールを確認する - 静的スコープには上限があるため、増え続ける対象は分割やアダプティブ スコープを前提に設計する

コメント