🐥

Microsoft Graph PowerShell SDKで条件付きアクセスのポリシーを更新する

2022/12/03に公開

はじめに

今回のゴールは「Microsoft Graph PowerShell SDKで、条件付きアクセスのポリシー設定を変更できるようになる」です。

Microsoft Graphとは

Microsoft公式の引用です。

Microsoft 365、Windows、および Enterprise Mobility + Security のデータにアクセスする際に使用できる統合型プログラミング モデルを提供します。
https://learn.microsoft.com/ja-jp/graph/overview

とりあえずMicrosoftのデータにアクセスするものかーという認識でOKです。
じゃあどうやってデータにアクセスするかは3つのコンポーネントを活用します。

Microsoft Graph API

単一のエンドポイントの https://graph.microsoft.com を提供し、RESTful APIとSDKを使用することでデータへのアクセスを可能にします。

あと2つのコンポーネントであるMicrosoft Graph コネクタとMicrosoft Graph データ接続の詳細は割愛します。

接続

Microsoft Graphモジュールをインストールします。
https://learn.microsoft.com/ja-jp/graph/sdks/sdk-installation#install-the-microsoft-graph-powershell-sdk

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
Install-Module Microsoft.Graph

Microsoft.Graph.Authentication(とUser)モジュールがインストールされます。

条件付きアクセスのポリシーを取得するGet-MgIdentityConditionalAccessPolicyはMicrosoft.Graph.Identity.SignInsモジュールに含まれます。
はじめてGet-MgIdentityConditionalAccessPolicyを利用した際にバックグラウンドでモジュールがインストールされるようです。

コマンドの確認

# 利用可能なコマンドレットの確認
(Get-Module Microsoft.Graph.Identity.SignIns).ExportedFunctions

# 条件付きアクセスに関するコマンドの検索
Get-Command -Name *conditionalaccess*

接続します。

Import-Module -Name Microsoft.Graph

# Microsoft Graphに接続
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"

実行するコマンドに応じて"Organization.Read.All","User.ReadWrite.All"などのアクセス許可を宣言します。
https://learn.microsoft.com/ja-jp/graph/permissions-reference#access-reviews-permissions

M365アカウントの認証を完了し、アクセス許可を承諾します。
※組織の代理人として同意するのチェックは不要です。

User.ReadWrite.Allなど管理者の同意が必要なアクセス許可は、管理者(Azure ADグローバル管理者等)のユーザーでないと未承認として扱われ一般ユーザーは承諾することができません。

組織の代理人として同意するのチェックをいれることで、一般ユーザーも管理者の同意が必要なアクセス許可を利用できるようになります。
(Azure AD > エンタープライズアプリケーション > アクセス許可 > 管理者の同意を付与するでも可能です。)

条件付きアクセスのポリシーを触ってみる

条件付きアクセスのポリシーを取得します。

Connect-MgGraph -Scopes "Policy.Read.All"
Get-MgIdentityConditionalAccessPolicy | fl

# 実行結果(1つのポリシーを抜粋)
Conditions           : Microsoft.Graph.PowerShell.Models.MicrosoftGraphConditionalAccessConditionSet
CreatedDateTime      : 2022/05/25 8:16:44
Description          :
DisplayName          : L001 Block ExchangeActiveSync
GrantControls        : Microsoft.Graph.PowerShell.Models.MicrosoftGraphConditionalAccessGrantControls
Id                   : ポリシーのID
ModifiedDateTime     : 2022/10/11 7:35:02
SessionControls      : Microsoft.Graph.PowerShell.Models.MicrosoftGraphConditionalAccessSessionControls
State                : enabled
AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#identity/conditionalAccess/policies/$entity]}

もう少し情報を取得したいです。
そんな時は。

Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId  ポリシーのID | Select-Object -ExpandProperty GrantControls | ConvertTo-Json

# 実行結果
{
    "GrantControls":  {
                          "BuiltInControls":  [
                                                  "block"
                                              ],
                          "CustomAuthenticationFactors":  [

                                                          ],
                          "Operator":  "OR",
                          "TermsOfUse":  [

                                         ]
                      }
}

色々見えてきました。
GrantControlsの型は?(上にあるけど改めて)

(Get-MgIdentityConditionalAccessPolicy).GrantControls | Get-Member

# 実行結果
TypeName: Microsoft.Graph.PowerShell.Models.MicrosoftGraphConditionalAccessGrantControls

型が分かったので作成してみます。

$AccessGrantControlsParam = @{
	TypeName = "Microsoft.Graph.PowerShell.Models.MicrosoftGraphConditionalAccessGrantControls"
	Property = @{
		BuiltInControls = "mfa","compliantDevice"
		Operator = "AND"
	}
}
$AccessGrantControls = New-Object @AccessGrantControlsParam

アクセス許可をブロックからMFAとIntune準拠デバイスの両方が必要に更新してみます。
まずはUpdate-MgIdentityConditionalAccessPolicyのアクセス許可を探します。

# MS Docsを参照
Get-Help Update-MgIdentityConditionalAccessPolicy -Online

# アクセス許可を探すコマンドもあるようです
Find-MgGraphCommand -Command Update-MgIdentityConditionalAccessPolicy -APIVersion v1.0| Select-Object -ExpandProperty Permissions | Select-Object Name,IsAdmin,Description

# 実行結果(APIVersionがv1.0のPermissionsです)
Name                               IsAdmin Description             
----                               ------- -----------
Application.Read.All               True    Read applications
Policy.Read.All                    True    Read your organization's policies
Policy.ReadWrite.ConditionalAccess True    Read and write your organization's conditional access policies

いよいよポリシーを更新してみます。

パターン1

Updateコマンドレットのオプションが利用できる場合です。

# Microsoft Graphに接続
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"

# GrantControlsオブジェクトの作成
$AccessGrantControlsParam = @{
	TypeName = "Microsoft.Graph.PowerShell.Models.MicrosoftGraphConditionalAccessGrantControls"
	Property = @{
		BuiltInControls = "mfa","compliantDevice"
		Operator = "AND"
	}
}
$AccessGrantControls = New-Object @AccessGrantControlsParam

# 更新
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId ポリシーのID -GrantControls @AccessGrantControls

# 実行結果の確認
Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId  ポリシーのID | Select-Object GrantControls | ConvertTo-Json

# 実行結果
{
    "GrantControls":  {
                          "BuiltInControls":  [
                                                  "mfa",
                                                  "compliantDevice"
                                              ],
                          "CustomAuthenticationFactors":  [

                                                          ],
                          "Operator":  "AND",
                          "TermsOfUse":  [

                                         ]
                      }
}

パターン2

Microsoft Graph PowerShellのコマンドレットでよく見るbodyparmeterで更新します。

# Microsoft Graphに接続
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"

# パラメーター(ハッシュテーブル)の作成
$params = @{
  GrantControls = @{
    BuiltInControls = @(
      "mfa"
      "compliantDevice"
    )
    Operator = "AND"
  }
}
# 更新
Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId ポリシーのID -BodyParameter $params

パターン3

Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"
Invoke-MgGraphRequestでREST APIっぽいことをします。
(Invoke-MgGraphRequestは最後の手段です。)

# Microsoft Graphに接続
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess"

# ポリシーのパラメーター(ハッシュテーブル)の作成
$Bodyparams = @{
  GrantControls = @{
    BuiltInControls = @(
      "mfa"
      "compliantDevice"
    )
    Operator = "AND"
  }
}

# リクエスト用のパラメーター(ハッシュテーブル)の作成
$RequestParams = @{
	Method = "PATCH"
	Uri = "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/ポリシーのID"
	Body = $Bodyparams | ConvertTo-Json
}
# 更新
Invoke-MgGraphRequest @RequestParams

# 実行結果の確認
(Invoke-MgGraphRequest -Method GET -Uri https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/ポリシーのID).grantControls

ただパターン3は次のようなエラーになりました・・・。
なぜでしょう・・・。
{"error":{"code":"BadRequest","message":"1007: Incoming ConditionalAccessPolicy object is null or does not match the schema of ConditionalAccessPolicy type.

クエリパラメータの利用

ODataV4.0の規格であるクエリパラメータを利用することで、GETで取得するデータをカスタマイズすることができます。
https://learn.microsoft.com/ja-jp/graph/query-parameters

コマンドレットによっては使えないパラメータもあります。

Filter

名前の通りフィルターします。

# 表示名がLから始まり、ポリシーが有効になっているものを取得
Get-MgIdentityConditionalAccessPolicy -Filter "startsWith(displayName,'L') and State eq 'enabled'"

クエリパラメータは別の機会に書きたいと思います。

Appendix

すべての条件付きアクセスを有効化するサンプルです。
テストしてみてご利用ください。

有効 レポート専用 無効
enabled enabledForReportingButNotEnforced disabled
# Microsoft Graphに接続
Connect-MgGraph -Scopes 'Policy.ReadWrite.ConditionalAccess'

# ポリシーの状態を上の表を参考に指定してください
$ConditionalAccessPolicyState = "enabled"

# ポリシーすべてを有効化
Get-MgIdentityConditionalAccessPolicy | ForEach-Object{ 
	Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $_.Id -State $ConditionalAccessPolicyState
}

# 表示名がLから始まるポリシーのみ有効化
Get-MgIdentityConditionalAccessPolicy -Filter "startsWith(displayName,'L')" | ForEach-Object{ 
	Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $_.Id -State $ConditionalAccessPolicyState 
}

# 実行結果の確認
Get-MgIdentityConditionalAccessPolicy | Select-Object -Property DisplayName,State

おわりに

PowerShell難しい。。

Discussion