🐉

PowerShellからGDAPの自動拡張を操作する

2024/01/04に公開

はじめに

この記事は、PowerShellコマンドレットを利用して既存のGDAPの自動拡張機能をまとめて有効化する方法について紹介しています。

GDAPの自動拡張機能

自動拡張機能の実装

2023年10月末に詳細な代理管理者権限(GDAP)の機能が拡張され、最大2年の期限切れのタイミングで、同設定のまま180日毎に自動拡張する自動拡張の機能が実装されました。本機能は既定が無効の状態で展開され、Opt-inにより有効化することが可能です。

Learnに記載のとおり、こちらの設定は個々の管理者リレーションシップの画面からだけではなく、一覧の画面からまとめて変更することも可能です。

自動拡張の実装における課題

本機能が実装されたのが、GDAPの機能がGAされてから1年以上経過され、旧来の委任された管理者特権(DAP)からの移行もほぼ完了したタイミングだったため、CSPパートナーがこの機能を利用する場合、既存の全てのGDAPに対してこれを設定しなければなりません。顧客の数が100や200程度であれば、前述の通り25件ずつ選択して自動延長を有効化すれば良いのですが、数千、数万の顧客を持つパートナーではそうもいきません。

当然、そういった大規模なパートナー向けにAPIも提供されていますが、サンプルのうちPowerShellのコマンドレットUpdate-MgTenantRelationshipDelegatedAdminRelationshipで変更しようとするとうまく動作しません

これは既にIssueとしても報告され、Backlogにも載っているのですが、残念ながら現時点でまだ改修されていません

一方で、早いテナントではそろそろGDAPの有効期限が近づいてきているようなケースもあります。また、30日前になると顧客側にも期限切れのリマインダメールが飛んでしまう[1]こともあり、パートナー側では今後速やかに対応を実施する必要がございます。

PowerShellから自動拡張を有効化する

前提条件

  1. PowerShell 5.1 以上(PowerShell 7 を推奨)
  2. Microsoft Graph PowerShell SDK のインストール
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Install-Module -Name Microsoft.Graph -Scope CurrentUser
  1. Microsoft.Graph.Identity.Partner のインストール
Install-Module -Name Microsoft.Graph.Identity.Partner -Scope CurrentUser

PowerShellからの自動拡張の変更

Invoke-MgGraphRequestコマンドレットを利用すると、ヘッダ、ボディに任意の値を設定してGraphAPIを叩くことができます。

APIリファレンスやPowerShellに-Debugを付けて実行した結果などを参照しつつ[2]書いてみた自動拡張を有効化するコマンドは以下の通りです。

$params = @{
  "autoExtendDuration" = "P180D"
}
Invoke-MgGraphRequest -Uri "v1.0/tenantRelationships/delegatedAdminRelationships/管理者リレーションシップID" -Method PATCH -Body $params -Headers @{"If-Match" = 管理者リレーションシップのエンティティタグ }
同様に、無効化する処理は期間にPT0Sを指定してこのように書けます
$params = @{
  "autoExtendDuration" = "PT0S"
}
Invoke-MgGraphRequest -Uri "v1.0/tenantRelationships/delegatedAdminRelationships/管理者リレーションシップID" -Method PATCH -Body $params -Headers @{"If-Match" = 管理者リレーションシップのエンティティタグ}

管理者リレーションシップIDやエンティティタグ(ETag)は、Get-MgTenantRelationshipDelegatedAdminRelationship PowerShellコマンドレットなどで調べることができます。[3]

全てのGDAPの自動拡張をPowerShellで有効化するサンプル

全体の処理の流れとしては以下の通りです:

  1. 管理者リレーションシップの一覧をCSVで取得する
  2. 取得したCSVファイルから処理する対象を選別し、変更処理の単位に分割する
  3. 2で作成したCSVを元にGDAPの自動拡張を有効化する
  4. 3をCSVの数だけ実行する

まず、CSVを配置する作業用フォルダを作成し、出力先ファイル名など情報を適宜変更の上スクリプトを実行します。スクリプトの拡張子を.ps1 として配置して呼び出しても良いですが、クリップボードから流し込みで実行する方が修正や部分的な再実行などが容易なので個人的には好みです。

認証を求められますのでPartner CenterテナントのEntra IDのグローバル管理者、かつAdminAgentsグループに所属している管理者アカウントでMFAを利用してログインします。
Connect-MgGraphで初めて認証する際は、アプリケーションのアクセス許可を求められるので、 承諾 します。

Collect-GDAP-Information.ps1
$OutFile = ".\GdapRelationships.csv"

Start-Transcript
Connect-MgGraph -Scopes "DelegatedAdminRelationship.Read.All"

$GDAPs = Get-MgTenantRelationshipDelegatedAdminRelationship -All

$counter = 1
$total = 1 + $GDAPs.Count
$denominator = "/"+[string]$Total

foreach ($GDAP in $GDAPs) {
  $GDAP | Add-Member Roles ($GDAP.AccessDetails.UnifiedRoles.RoleDefinitionId -join ":") -force
  $GDAP | Add-Member CustomerDisplayName $GDAP.Customer.DisplayName -force
  $GDAP | Add-Member CustomerTenantId $GDAP.Customer.TenantId -force
  $GDAP | Add-Member eTag $GDAP.AdditionalProperties['@odata.etag'] -force
  $GDAP | select Id,DisplayName,CustomerDisplayName,CustomerTenantId,Roles,Status,AutoExtendDuration,CreatedDateTime,EndDateTime,LastModifiedDateTime,eTag | Export-Csv $OutFile -Encoding UTF8 -Append

  $per = ($counter / $total * 100)
  Write-Progress -activity "inProgress" -status $counter$denominator -percentComplete $per
  $counter ++;
}

Disconnect-MgGraph
Stop-Transcript

実行が終わると、管理者リレーションシップ一覧がGdapRelationships.csvに出力されます。

このCSVを加工してターゲットリストを作成します。そのまま使っても良いですが、終了したActive以外のステータスのGDAPもリストには含まれているので紛らわしいので必要に応じて削除します。

本番環境での実行を意識した場合、分割して実行するケースが多いかと思います。感覚的に初回はテストテナント(5以下)で実施した後、本番は10→100→1000→1000(…以下繰り返す)程度の分割が良いように感じます。実行時間の推測が必要な場合は100程度実行してみてその速度を見て推察することになりますが、あくまで参考に留めて余裕を持ったスケジューリングをするのが良いでしょう。[4]

Update-GDAPAutoExtend.ps1
$InputFile = ".\GdapRelationships.csv"

Start-Transcript
Connect-MgGraph -Scopes "DelegatedAdminRelationship.ReadWrite.All"

Function Enable-GDAPAutoExtend(){
  param(
    [string]$delegatedAdminRelationshipId,
    [string]$eTag
  )
  $params = @{
    "autoExtendDuration" = "P180D"
  }
  Invoke-MgGraphRequest -Uri "v1.0/tenantRelationships/delegatedAdminRelationships/$($delegatedAdminRelationshipId)" -Method PATCH -Body $params -Headers @{"If-Match" = $eTag}
}

$Targets = Import-csv $InputFile | ? ($_.Status -eq "active")}
foreach ($Target in $Targets){
  Enable-GDAPAutoExtend -delegatedAdminRelationshipId $Target.Id -eTag $Target.eTag
}

Disconnect-MgGraph
Stop-Transcript

おわりに

PowerShellを利用すると、日々の定型処理を簡単かつ確実に実施することができます。また、PowerShellのコマンドレットがまだ実装されていないような処理でも、直接APIを叩くことにより処理を代替することもできます。少しでもDo more with lessできるよう、是非皆様の日々の運用業務にご活用頂ければ幸いです。

脚注
  1. 自動拡張が有効化されている場合は期限切れ30日前/7日前/1日前のリマインダメールは飛ばない ↩︎

  2. 多くのPowerShellコマンドレットではDebugスイッチをつけてコマンドを実行すると具体的にどのようなヘッダ、ボディで、どのAPIを叩いているかなどを見ることができます。APIリファレンスで理解が難しい場合などには有用です ↩︎

  3. エンティティタグは、プロパティが更新される度に変更されますので、同一のオブジェクトに対して再度変更をする場合は値を取り直す必要があります ↩︎

  4. 3000や5000だとダメかといわれるとそうではないですが、あまり長すぎても実行時間が読めなかったりするので。スロットリングなどが掛かる場合は適宜スリープなどの処理を入れて調整。例えば月初は処理が重いなど、時期によってのAPI側の応答速度に違いが出るケースもありうる。API側の調子が悪いこともあり得るので、何かおかしい場合は日を改めてなどの対応も有用 ↩︎

Microsoft (有志)

Discussion