Microsoft365でユーザー単位MFA認証の有効無効をPowershellで操作する

(2023/04/18 追記)
[メモ](#メモ)に記載しましたが、Powershellを利用したユーザー単位のMFA有効/無効の切り替えは今後サポートされないようです。
代替策としては、条件付きアクセス等を用いた操作になります。(コマンドでは出来なさそう)

# 前書き
Google Workspace（旧G Suite）やMicrosoft365（旧Office365）などの、クラウドグループウェアサービスを導入する企業が増加傾向にあるのは、特にしっかりとデータなどを用意しなくても、昨今のクラウドファーストやDXの声などから窺い知ることが出来そうな物です。
こういったサービスを企業に導入していくには様々な課題が生じますが、その中の「セキュリティ」「多要素認証」あたりからちょっとコアな記事です。
コアと言っても、タイトルの通りのことをするのですが、一部クセがあったのでその備忘録になります。

# 準備
## Microsoft365で全体管理者権限のユーザを用意する
今回の操作は、Microsoft365の全体管理者（または、グローバル管理者）の権限を持ったユーザーが必要です。
Microsoft365管理センターの左メニューから、「役割」＞「役割の割り当て」を選ぶと、おすすめの項目に目的の権限が見つかります。
権限を選んだ後に、ユーザーの追加を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959834/17edfdf0-e180-d5c7-80fb-6e6e6d2c00c9.png)

ユーザーの追加ページでは、追加したいユーザーを検索なりしたあとに、ユーザーを選択して「追加」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959834/9a2813cf-e204-1c3e-391e-b759e01f35f7.png)

これで全体管理者にユーザーを追加できました。

## Powershellでパッケージのインストールをする
Powershellで操作したいので、Powershellに必要なパッケージをインストールしていきます。
```powershell
Install-Module MSOnline
```
環境によってはインストール時に、「NuGetプロバイダーが必要です」とか「信頼していないリポジトリからモジュールのインストールです」とか言われます。
大体Y押してEnterで解決します。（もちろん、インストールする前に何をインストールしているのかを理解してから実施するべきです。）
モジュールインストールがされているかも念のため確認しておきます。
```powershell
Get-InstalledModule -Name MSOnline
```
大体以下のような出力になると思います。
```
PS C:\> Get-InstalledModule -Name MSOnline

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.1.183.66 MSOnline                            PSGallery            Microsoft Azure Active Directory Module for Wind...
```

# PowerShellでMFA設定を操作する
## Azure ADに接続する
ここから本番。設定の操作をするには、まずAzure ADに接続する必要がありますので、以下のコマンドで接続をします。
```Powershell
Connect-MsolService
```
コマンド実行後、小さいウィンドウが立ち上がってMicrosoft365のサインインを求められます。
ここでは全体管理者を付与したユーザーでサインインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959834/06807cbe-0d95-67ef-516e-f5135c57f733.png)

サインインに完了すると、特にログが出ないですがAzure ADに接続された状態になります。

## MFAの「状態」
有効以外にも共通するのですが、「特定のユーザー」の「StrongAuthenticationRequirement」オブジェクトの値を弄ることでMFAの状態を操作します。
MFAの状態は以下の3つがあります。
- 有効（Enable）
- 強制（Enforce）
- 無効（Disable）

有効と強制はどう違うの？って話ですが、基本的に「有効」になるようにしておけば良いかと思います。
「有効」になったユーザーは次のサインイン時にMFAのセットアップを行いますが、そのセットアッププロセスが完了すると自動的に「強制」に切り替わります。
また、Microsoftの公開文書では、MFA登録済みだったり、レガシー認証が突然使えなくなることを許容できる場合を除いて、「強制」に手動変更しない方が良いと記載があり、リスクが生じるようです。

## MFAを有効にする
有効にするには、以下のコマンドを実行します。
```powershell
# StrongAuthenticationRequirementをもつオブジェクトを作って値を入れる
$MFA = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$MFA.RelyingParty = "*"
$MFA.State = "Enable"
$MFArr = @($MFA)
# 作ったオブジェクトをユーザーの設定変更コマンドに配列として渡す
Set-MsolUser -UserPrincipalName test@XXX.onmicrosoft.com -StrongAuthenticationRequirements $MFArr
```
MFAを有効にすると、そのユーザーは次回サインイン時にMFAのセットアップを求められます。

## MFAを強制にする
Stateが`Enable`から`Enforced`に変わるだけです。
```powershell
# StrongAuthenticationRequirementをもつオブジェクトを作って値を入れる
$MFA = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$MFA.RelyingParty = "*"
$MFA.State = "Enforced"
$MFArr = @($MFA)
# 作ったオブジェクトをユーザーの設定変更コマンドに配列として渡す
Set-MsolUser -UserPrincipalName test@XXX.onmicrosoft.com -StrongAuthenticationRequirements $MFArr
```

## MFAを無効にする
ここだけクセあります。
Stateに`Disable`を入れると思いきや、StrongAuthenticationRequirementsに空の配列を与えます。
```Powershell
# 空の配列をユーザーの設定変更コマンドに配列として渡す
Set-MsolUser -UserPrincipalName test@XXX.onmicrosoft.com -StrongAuthenticationRequirements @()
```

# メモ
- 条件付きアクセスポリシーが要件上利用出来ない、ある日「我が社はこれから全社員MFAを使いなさい!」って時に使えそう。
- テナント全体のセキュリティ規定値機能によってMFAを有効にしている場合、この手段は通用しないかも。
- 条件付きアクセス機能を使っている場合も、あまり利用しないことだと思います。
- MSOnlineモジュールはMicrosoftの公開情報によると廃止予定です。
    - https://jpazureid.github.io/blog/azure-active-directory/azure-ad-change-management-simplified/
    - ただし、参考資料に記載した公開情報では、MSOnlineモジュールでのみ操作できるとも。MicrosoftGraph Powershellに統合されていくのでしょうか…？
    - (2023/04/18 追記)
        - コマンドによるStrongAuthenticationRequirementsの値の操作は、下記の代替コマンド表に掲載されていないので、今後サポートされない模様です。
        - https://learn.microsoft.com/en-us/powershell/microsoftgraph/azuread-msoline-cmdlet-map?view=graph-powershell-1.0
        - 今後は[条件付きアクセス](https://learn.microsoft.com/ja-jp/azure/active-directory/conditional-access/howto-conditional-access-policy-all-users-mfa)などを用いて設定する方が良さそう。

# 参考資料
https://learn.microsoft.com/ja-jp/azure/active-directory/authentication/howto-mfa-userstates