ルドルフもわたるふもいろいろあってな

Microsoft 365、Power Platform、PowerShellについて調べたことや検証したことなどを投稿します。技術の話は面白い。

PowerShellでアイテム保持ポリシーを一括作成する

f:id:wataruf01:20220330194611p:plain:h300

主旨

アイテム保持ポリシーを一括作成するPowerShellの説明です。

そもそも「アイテム保持ポリシー」とは?

アイテム保持ポリシーとはテナント内に登録された様々なデータを一定期間保持する機能です。保持する対象として指定できるものは以下の通りです。

  • Exchange メール
  • SharePoint サイト
  • OneDrive アカウント
  • Microsoft 365 グループ
  • Skype for Business
  • Exchange パブリック フォルダー
  • チームのチャネル メッセージ (標準チャネルだけでなく共有チャネル が含まれます)
  • Teams のチャット
  • Teams の非公開チャネル メッセージ
  • Yammer コミュニティのメッセージ
  • Yammer ユーザーのメッセージ

ソースコードと解説

ソースコード

PowerShellソースコードは以下の通りです。

#----------------------------------------------------
#入力情報
#----------------------------------------------------
#実行ユーザーの認証情報
$adminUserName  = "***@M365x88795794.onmicrosoft.com"
$securePassword = "****" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($adminUserName, $securePassword)

#インプット用CSVのファイルパス
$csvFilePath = ".\input.csv"

#実行ログのファイルパス
$logFile = ".\log_" + (Get-Date).ToString("yyyyMMdd_HHmm") + ".log"

#----------------------------------------------------
#ファンクションの定義
#----------------------------------------------------
#【ファンクション】アイテム保持ポリシーの作成
function CreatePolicy ()
{
    Param
    (
        [Parameter(Mandatory=$true)] [String]$PolicyName,
        [Parameter(Mandatory=$true)] [String]$Location,
        [Parameter(Mandatory=$true)] [String]$RetentionDuration,
        [Parameter(Mandatory=$false)][ValidateSet("Delete","Keep","KeepAndDelete")][String]$RetentionComplianceAction,
        [Parameter(Mandatory=$true)] [String]$DummyObject
    ) 

    #ポリシーの作成を実行
    if($Location -eq "ExchangeLocation")
    {
        $policyParameter = `
        @{
            "Name"        = $PolicyName
            "Application" = @("User:MicrosoftTeamsChannelMessages")
            $Location     = $DummyObject
            "Enabled"     = $true
        }

        $policy = New-AppRetentionCompliancePolicy @policyParameter

        $ruleParameter = `
        @{
            "Name"                      = $PolicyName
            "Policy"                    = $policy.Guid
            "RetentionDuration"         = $RetentionDuration
            "RetentionComplianceAction" = $RetentionComplianceAction
        }

        New-AppRetentionComplianceRule @ruleParameter
    }
    else
    {
        $policyParameter = `
        @{
            "Name"    = $PolicyName
            $Location = $DummyObject
            "Enabled" = $true
        }

        $policy = New-RetentionCompliancePolicy @policyParameter

        $ruleParameter = `
        @{
            "Name"                      = $PolicyName
            "Policy"                    = $policy.Guid
            "RetentionDuration"         = $RetentionDuration
            "RetentionComplianceAction" = $RetentionComplianceAction
        }

        New-RetentionComplianceRule @ruleParameter
    }
}

#-------------------------------------------------
#コンプライアンスセンターへの接続
#-------------------------------------------------
Connect-ExchangeOnline -Credential $credential
Connect-IPPSSession -UserPrincipalName $adminUserName

#-------------------------------------------------
#アイテム保持ポリシーの作成
#-------------------------------------------------
#CSVの読み込み処理
$csvDatas = @()
$csvDatas += `
Import-Csv -Path $csvFilePath -Encoding UTF8 `
| select @{Name = "PolicyName";                Expression = {$_.PolicyName.trim()}},`
         @{Name = "Location";                  Expression = {$_.Location.Trim()}},`
         @{Name = "RetentionDuration";         Expression = {$_.RetentionDuration.Trim()}},`
         @{Name = "RetentionComplianceAction"; Expression = {$_.RetentionComplianceAction.trim()}},`
         @{Name = "DummyObject";               Expression = {$_.DummyObject.Trim()}}

foreach($record in $csvDatas)
{
    CreatePolicy  `
    -PolicyName                $record.PolicyName `
    -Location                  $record.Location  `
    -RetentionDuration         $record.RetentionDuration   `
    -RetentionComplianceAction $record.RetentionComplianceAction  `
    -DummyObject               $record.DummyObject
}

入力情報(CSV)

このスクリプトCSVを入力情報としています。以下の列があるCSVを準備します。

  • PolicyName(ポリシー名)
  • Location (保持対象の種類)
  • RetentionDuration (保持期間)
  • RetentionComplianceAction (保持期間が終了したときのアクション)
  • DummyObject (ダミーデータ)

f:id:wataruf01:20220330200422p:plain

「Location (保持対象の種類)」とは?

アイテム保持ポリシーは保持対象の種類を内部的に Location と呼んでいます。

以下のように製品ごとに内部的な名称があります。

  • Exchange メール (ExchangeLocation)
  • SharePoint サイト(SharePointLocation)
  • OneDrive アカウント (OneDriveLocation)
  • Microsoft 365 グループ (ModernGroupLocation)
  • チームのチャネル メッセージ (TeamsChannelLocation)
  • Teams のチャット(TeamsChatLocation)
  • Teams の非公開チャネル メッセージ(ExchangeLocation)

保持対象の種類ごとに使用するパラメータが異なるのが特徴です。
f:id:wataruf01:20220330201137p:plain

「DummyObject (ダミーデータ)」とは?

保持ポリシーに対して保持対象を個別に登録できるようにするため、ポリシー作成時にダミーデータをひとつします。

保持ポリシーの適用対象は「テナント内にあるすべての○○○(例:ユーザー、チーム、サイト)」とするか「個別の○○○(例:ユーザー、チーム、サイト)」を指定できます。ただし、後者を選択するためにはポリシーの作成時にひとつ以上の適用対象を指定する必要があります。

今回作成したスクリプトでは、個別の保持対象はポリシー作成後に別途追加する運用を前提しているため、ポリシーの作成時にはまだ具体的な保持対象がありません。そのため、ポリシー作成時にはダミーデータをひとつ登録するようにしています。

ポリシー作成の内部的な仕組み

アイテム保持ポリシーの作成は2つの工程がある。

アイテム保持ポリシーの作成は、以下の2つの工程にわけられます。コンプライアンスセンターをブラウザで開いてアイテム保持ポリシーを作成する場合は、ルールの作成は内部的に自動で行われるため工程が2つあることに気づきにくいです。
・ポリシーの作成
(New-RetentionCompliancePolicy)
・ルールの作成
(New-RetentionComplianceRule)

アイテム保持ポリシーをひとつ作成するスクリプト(Teams の非公開チャネル メッセージ以外):

$plicyName  = "20220329_Group_TeamsChannelLocation_年数指定_04"
$dummyObject = "dummy02@M365x88795794.onmicrosoft.com"

$policy = New-RetentionCompliancePolicy `
-Name         $plicyName `
-(保持対象に紐づくパラメータ) $dummyObject `
-Enabled        $true

New-RetentionComplianceRule `
-Name                      $plicyName `
-Policy                    $policy.Guid `
-RetentionDuration         2555 `
  • RetentionComplianceAction Keep

「Teams の非公開チャネル メッセージ」は使用するコマンドが異なる。

「Teams の非公開チャネル メッセージ」とはプライベートチャネルのことです。プライベートチャネルについては、他の種類の保持対象とは使うコマンドが異なります。特徴的なのは下記の赤字の部分です。

この特徴は、ポリシーへの保持対象追加(Set)やポリシーの削除(Remove)でも共通です。


アイテム保持ポリシーをひとつ作成するスクリプト(Teams の非公開チャネル メッセージ):

$policy = New-AppRetentionCompliancePolicy `
-Name       $plicyName `
-Applications "User:MicrosoftTeamsChannelMessages" `
-ExchangeLocation $dummyObject `
-Enabled      $true

New-AppRetentionComplianceRule `
-Name $plicyName `
-Policy $policy.Guid `
-RetentionDuration Unlimited `
-RetentionComplianceAction Keep

からめもさんに感謝

アイテム保持ポリシーはひとつのポリシーに複数の種類の保持対象(Location)を含めることができます。

しかしながら、要件の都合で今回作成したスクリプトでは、ひとつのポリシーにはひとつの種類の保持対象(Location)のみを含めることを前提としています。そのため、コマンドで使用するパラメータが保持対象の種類ごとに異なる点にどうやって対応するかに悩みました。

困っていたところ、からめもさんから助言をいただきました。
f:id:wataruf01:20220330203534p:plain

教えていただいたDocsの記事に記載されているハッシュ テーブルスプラッティングで、パラメーター名とパラメーターと値のペアをコマンドに渡す方法を使うことで解決ができました。ありがとうございます。