Microsoft365のExchangeをメールに使っている方、「ユーザー毎にメールボックス容量の使用率を監視したいなぁ」なんて考えたことありませんか?

弊社ではそんなことがありました。

対応方法を調べたところいろいろやりようはあるみたいですが、どれもしっくりきません。

  • Exchangeの管理画面で見る
    → 自分から見に行く手間がかかる
  • メールボックス容量の閾値をオーバーしたら通知する機能を使う
    → オーバーする前に知りたい
  • Power BI Proに課金すればグラフィカルに集計してさらに配信もできる?
    → お金はかけたくない

お手上げ状態になってしまったので、試しにMicrosoft 365サポートに聞いてみました。

Q:
Microsoft365に、Exchangeに登録しているユーザー毎にメールボックス容量の使用率を集計して、それを特定の宛先に定期配信する機能はありますか?

すると次のような返事をいただきました。

A:
Microsoft 365に当該機能はありません。
しかし、PowerShellを使えばExchangeに登録している全ユーザーのメールボックス最大容量と使用容量を取ることができます。

これだ!と思いました。

PowerShellならメール送信もできるみたいなので、それと組み合わせてバッチにすれば事前にメールボックス容量の使用率を把握することができそうです。

という訳で、さらにいろいろ聞いたり自分でも調べたりしながらメールボックス容量の使用率を集計するPowerShellのバッチを作りました。

前置きが長くなりましたが、今回は「PowerShell(.ps1)でMicrosoft Exchange Onlineのメールボックス容量の使用率を集計してさらにCSV出力する方法」をご紹介したいと思います。

事前準備

まずは事前準備としてPowerShellでMicrosoft Exchange Onlineに接続できるようにします。

作業環境がmacのため、それベースにまとめます。

PowerShellをインストールする

ターミナルを起動してmacにPowerShellインストールします。

x@macbook ~ % brew install --cask powershell

PowerShellを起動する

インストールできたらpwshでPowerShellを起動します。

x@macbook ~ % pwsh
PowerShell 7.2.1
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS /Users/x>

PowerShellでExchangeに接続するのに必要なモジュールをインストール

Exchange Online PowerShellモジュールというモジュールをインストール・インポートします。

インストールで警告が表示されたら「Y」で進めます。

PS /Users/x> Install-Module -Name ExchangeOnlineManagement
PS /Users/x> Import-Module ExchangeOnlineManagement

接続テスト

Connect-ExchangeOnlineでExchangeに接続します。

PowerShellでExchangeにアクセスするとGUIでユーザー認証を行う仕様になっているようなので、その画面が表示されたらMicrosoft365のログインパスワードを入力してサインインします。

PS /Users/x> Connect-ExchangeOnline -UserPrincipalName <Microsoft365のログインID>

ここまではMicrosoft365のドキュメントでも紹介されていますが、Microsoft365サポートの方が完全CUIでログイン認証を完結させるコマンドも教えてくれました。

それが以下です。

$password = ConvertTo-SecureString "<Microsoft365のログインパスワード>" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("<Microsoft365のログインID>", $password)
$o365Cred = Get-Credential -cred $credential
Connect-ExchangeOnline -Credential $o365Cred

以上でPowerShellでMicrosoft Exchange Onlineに接続できる状態になりました。

PowerShellのバッチを書く

機能は大まかに次の通りです。

  • Exchange Onlineに接続して全ユーザーのメールボックス使用量と最大容量を取得する
  • 取得したメールボックス使用量と最大容量からユーザー毎の使用率を求める
  • ユーザー毎にメールボックス使用量、最大容量、使用率をCSVファイルに出力する

以上の全体像が次の通りです。

CSVの出力先やMicrosoft365のログイン情報はハードコーディングしています。

各関数の処理の詳細は後述します。

# -----------------------------------------------------------------------------------
# メールボックス使用率を集計する
# -------------------------------------

$put_dir = "./"
$put_file = $put_dir + "usage_rate.csv"
$user_name = "<ユーザー名>"
$user_pass = "<パスワード>"

# -------------------------------------
# メールボックス使用量と上限値を取得する
# ------------------
function get_mailbox_size( $user_name, $user_pass ) {

	$password = ConvertTo-SecureString $user_pass -AsPlainText -Force
    $credential = New-Object System.Management.Automation.PSCredential($user_name, $password)
    $o365Cred = Get-Credential -cred $credential

    Connect-ExchangeOnline -Credential $o365Cred

    $total_size_list = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Foreach{Get-MailboxStatistics -Identity $_.Identity | Select DisplayName,TotalItemSize}
    $max_size_list = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited | Select PrimarySmtpAddress,ProhibitSendReceiveQuota

    return $total_size_list, $max_size_list
}

# -------------------------------------
# メールボックス使用率をcsvに出力する
# ------------------
function put_mailbox_size( $put_file, $total_size_list, $max_size_list ) {

    for ( $i = 0; $i -lt $max_size_list.Length; ++$i ) {
        $total_size = format_data $total_size_list[$i].TotalItemSize
        $max_size = format_data $max_size_list[$i].ProhibitSendReceiveQuota
    	$usage_rate = [Math]::Round(($total_size.Replace(",","") / $max_size.Replace(",","")) * 100, 0)

        $products += @(
            [pscustomobject]@{
                MailAddress = $max_size_list[$i].PrimarySmtpAddress
                UsageRate_percent = $usage_rate
                UsedSize_byte = $total_size
                MaxSize_byte = $max_size
            }
        )
    }

    $products | Export-Csv -Encoding UTF8 -NoTypeInformation -Path $put_file
}

# -------------------------------------
# 置換
# ------------------
function format_data( $data ) {
    $ret = $data -match "(?<=\()[^\(\)]+(?=\))"
    return $Matches[0].Replace(" bytes","")
}

$total_size_list, $max_size_list = get_mailbox_size $user_name $user_pass
put_mailbox_size $put_file $total_size_list $max_size_list

Exchange Onlineに接続して全ユーザーのメールボックス使用量と最大容量を取得する関数

get_mailbox_size()でExchange Onlineに接続して全ユーザーのメールボックス使用量と最大容量を取得します。

ユーザー毎のメールボックス容量使用率を求めてCSV出力する関数

メールボックスの使用率は自分で計算して求めます。

以上のバッチを.ps1で任意の場所に保存します。

PowerShellのバッチを実行

保存したps1ファイルをターミナルから実行します。

x@macbook ~ % /usr/local/bin/pwsh -File /xxx/yyy/batch.ps1

そうすると、メールボックス使用率などが一覧で書かれたCSVファイルがスクリプトと同じディレクトリに保存されます。

まとめ

以上が「PowerShell(.ps1)でMicrosoft Exchange Onlineのメールボックス容量の使用率を集計してCSV出力する方法」です。

このバッチをcronで定期実行させてメールボックス使用率を監視しています。

Microsoft365のExchangeメールボックス使用率を監視したい方の参考になればと思います。