メールボックスにテスト用のメールをぶち込みたくて、とりあえずメール送信を自動化するスクリプトを作成した。
※ 2020/07/31 スクリプトを一部修正しました。
手順は、大まかに以下の通り。
- Microsoft 365の用意
- Microsoft 365のAzure Active Directoryにアプリケーション登録
- スクリプトの作成
最終的に出来上がったコードは以下。
$header = @{"Content-type"="application/x-www-form-urlencoded"}
$body = @{client_id='<input-your-clientID>';scope='https://graph.microsoft.com/.default';client_secret='<input-your-secret';grant_type='client_credentials'}
$url = "https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token"
$response = Invoke-WebRequest -Headers $header -Method Post -Body $body $url
$json = ConvertFrom-Json $response.Content
$token = "Bearer " + $json.access_token
$header2 = @{"Content-type"="application/json";"Authorization"="$token" }
$body2 = '{"message": { "subject": "Meet for lunch?", "body": {"contentType": "Text", "content": "The new cafeteria is open."},"toRecipients": [{"emailAddress": {"address": "<input-receiver-mailAddress"}}],"ccRecipients": []},"saveToSentItems": "false"}}'
$url2 = "https://graph.microsoft.com/v1.0/users/{input-sender-mailAddress}/sendMail"
$response2 = Invoke-WebRequest -Headers $header2 -Method Post -Body $body2 $url2
$response2.StatusCode
※ 動かなかったらごめんなさい
アプリケーションIDなどは、以下の2章にあるリンク先のページを読めば、何を指定すればいいかわかるはずです。
(Azure Active DirecrtoryのアプリのアプリケーションID、テナントID、クライアントシークレットなんだけどね)
$response2.StatusCodeが202なら成功。
ちなみに、MFAが有効なユーザーを送信者に指定しても、メール送信できた。
以下、大まかに作成に至るまでの流れ。
#1. Microsodt 365の準備
今回は開発者用の無償サブスクリプションを使用しました。テストユーザーも自動で作ってくれるし、らくちん。
#2. Microsoft 365のAzure Active Directoryにアプリケーション登録
スクリプトからメール送信するためには、リクエストにトークンを付与する必要がある。
以下のページに従って準備する。
https://docs.microsoft.com/ja-jp/graph/auth-v2-service?view=graph-rest-1.0
ただし、以下の点だけページとは異なる。
(1) トークンの応答を受け取るためのサービスのリダイレクト URLは、特に指定しなくていい。
(2) Microsoft Graphのアクセス許可で、Mail.Sendを許可。
#3. スクリプトの作成
以下のページに従って作成。
https://docs.microsoft.com/ja-jp/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http
#4. 最後に
あとはまあ、この処理をテキトーにループさせてやればいいんじゃなかろうか?
ただ、Graph APIは10分間に10000回のコールだとか、メール受信は1時間に3600回までだとかいろいろ制限があるし、
そもそも短時間に大量のリクエストを出すと危険だし迷惑なので、ループで回すときは
(1) 無限ループにならないようにする
(2) 送信と送信の間にインターバルを数秒とる
などして、攻撃と誤認されないような工夫をしましょう・・・・
あと、プロキシ環境下では試してないけど、たぶん使えなさそう。
以上!