こんにちは。日本マイクロソフト Exchange & Outlook サポート チームの山内です。
Exchange Online EWS: 廃止期限が迫っています では、ほとんどのアプリは限られた EWS の機能しか使用しておらず、AI を活用した移行などの最新ツールを使うことで、想像しているよりも簡単に移行できるケースが多いと紹介しました。
とはいえ、実際の EWS アプリを AI に渡すと、どこまで Microsoft Graph へ移行できるのでしょうか。移行前と同じ動作を保てるのか、コード以外に何を変更し、人は何を確認する必要があるのかも気になるところです。
そこで今回は、読者も手元で検証しやすいように、受信トレイのメールを取得する小さな PowerShell スクリプトを GitHub Copilot で Microsoft Graph 版へ変換し、実際に動かしてみます。ここで紹介する進め方は、C# など他の言語で作られた EWS アプリにも応用できます。変換前後の結果を比べながら、AI を活用した移行がどの程度手軽に進められるのかを確認します。
想定読者と本記事の位置付け
本記事は、EWS を利用したアプリケーションおよび AI を使用したアプリケーションの開発経験があり、Microsoft Graph への移行を検討しているアプリケーション開発者を対象としています。
本記事は、Exchange Online の管理者を対象とした記事ではありません。また、アプリケーション開発の経験がない管理者が、本記事を参考に AI を使って自力で Microsoft Graph への移行を行うことを推奨するものでもありません。
AI は移行作業を支援するためのツールであり、生成されたコードをそのまま利用できるとは限りません。必ず、AI の出力を技術的にレビューし、必要に応じて修正できるアプリケーション開発者が、移行作業と動作確認を行ってください。
本記事では、Visual Studio Code で GitHub Copilot を利用できるように構成されている環境を前提としています。
今回変換する EWS コード
変換元は、EWS の FindItem を使って、指定したメールボックスの受信トレイから最新 10 件を取得するスクリプトです。表示する項目は次の 3 つだけです。
- 受信日時
- 差出人の表示名
- 件名
スクリプト全体はこちらから確認できます。
Get-EwsInboxMessages.ps1このスクリプトでは、OAuth 2.0 のクライアント資格情報フローで EWS 用のアクセス トークンを取得し、SOAP リクエストを https://outlook.office365.com/EWS/Exchange.asmx へ送信しています。
まず EWS 版を動かしてみる
Client Secret はコードに書かず、実行時に SecureString として入力します。実際の値へ置き換えるのは Tenant ID、Client ID、メールボックスの 3 か所です。
1 | $clientSecret = Read-Host "Client Secret" -AsSecureString |
受信トレイの最新 10 件が、ReceivedDateTime、From、Subject の 3 列で表示されます。この結果を、変換後の動作を確認するための基準にします。

Copilot に変換を依頼する
Get-EwsInboxMessages.ps1 を Get-GraphInboxMessages.ps1 という名前でコピーし、コピーしたファイルを Visual Studio Code で開きます。その状態で GitHub Copilot Chat に次のプロンプトを渡します。
実際のアプリでは、使っている EWS の操作や入出力をすべて把握し、プロンプトに列挙することが難しい場合があります。そこで、具体的な API や処理内容は指定せず、まずコードから現在の動作を読み取るように依頼します。また、EWS と Microsoft Graph は必ずしも 1 対 1 で対応しないため、単一の API 呼び出しではなく、必要に応じて周辺のコードも変更しながらアプリ全体の動作を保つように依頼します。
1 | このワークスペースにある EWS を使用したアプリケーションを分析し、Microsoft Graph を使用する実装へ移行してください。 |
1 対 1 で対応する Graph API がないことだけで、アプリ全体を移行できないとは限りません。複数の API やアプリ側の処理で同じ結果を実現できる場合があります。それでも動作を維持できない場合は、理由と変換可能になる条件を示してもらうことで、要件の見直しや代替方法を判断できます。
プロンプトはテキスト ファイルでもダウンロードできます。
copilot-prompt.txt
生成されたコードを確認する
生成 AI の性質上、GitHub Copilot の生成結果は常に同じになるとは限らず、使用するモデル、対象のコード、プロンプトを実行したときのコンテキストなどによって変わります。以下は、今回のスクリプトに対する生成結果を人が確認した一例です。コードは 1 回の依頼で Microsoft Graph 版へ変換されましたが、EWS 版と実行結果を比較したところ、受信日時に 9 時間の差が見つかりました。同じプロンプトを使っても、必ず同じコードが生成されるわけではないため、生成後のレビューと動作確認は必要です。
変換後のスクリプト全体はこちらです。
Get-GraphInboxMessages.ps1主な変更は 3 か所だったことがわかります。
- アクセス トークンの対象を
https://outlook.office365.com/.defaultからhttps://graph.microsoft.com/.defaultへ変更する。 - SOAP の
FindItemを、Microsoft Graph の/users/{mailbox}/mailFolders/inbox/messagesへの GET リクエストへ変更する。 - XML の EWS 応答ではなく、JSON の
valueから受信日時、差出人、件名を取り出す。
Microsoft Graph へのリクエスト部分は、次のようにかなり短くなりました。
1 | $mailboxPath = [System.Uri]::EscapeDataString($Mailbox) |
検証環境では、生成されたコードのまま実行すると、EWS 版と Microsoft Graph 版の受信日時に 9 時間の差がありました。日時の扱いを次のように 1 行調整したところ、同じ結果になりました。
1 | ReceivedDateTime = ([datetimeoffset]$_.receivedDateTime).UtcDateTime |
パラメーターと出力プロパティ名は EWS 版から変えていません。API の内側は SOAP から REST へ変わりましたが、スクリプトを呼び出す側への影響は抑えられています。
Microsoft Entra ID のアクセス許可を変更する
GitHub Copilot の応答に、必要な権限として Microsoft Graph のアプリケーション権限 Mail.ReadBasic.All と書かれており、技術的に確認しても Mail.ReadBasic.All のアクセス許可が妥当となるので、以下の通りアクセス許可を変更します。
より複雑なアプリなどでアクセス許可を設定する場合は、アプリによって複数のアクセス許可が必要な場合など、今回のアクセス許可と異なる場合があります。
- Microsoft Entra 管理センター で対象のアプリ登録を開き、[API permissions] から Microsoft Graph のアプリケーション権限
Mail.ReadBasic.Allを追加します。 - 追加したアクセス許可に管理者の同意を付与します。
- [App registrations] の構成済みアクセス許可から、Office 365 Exchange Online の
full_access_as_appを削除します。 - 同じ [API permissions] 画面下部の、テナントに付与されたその他のアクセス許可の一覧で、
full_access_as_appのメニューから [管理者の同意を取り消す] を選びます。


[App registrations] からアクセス許可を削除する操作は、アプリが今後要求するアクセス許可の構成を変更するものです。削除後も、既に付与された EWS のアプリケーション権限は同じ [API permissions] 画面下部に表示されます。EWS の権限を確実に外すため、そのメニューから管理者の同意も取り消します。
今回のスクリプトが取得するのは基本的なメール プロパティだけなので、Mail.ReadBasic.All を使います。本文、添付ファイル、拡張プロパティなどを取得するアプリでは要件が異なるため、実際に使っているデータに合わせて権限を選びます。
Microsoft Graph 版を EWS 版と同じ条件で動かしてみる
権限の変更が反映されたら、EWS 版と同じパラメーターで Microsoft Graph 版を実行します。今回の例では変わるのはスクリプトのファイル名だけでした。
1 | $clientSecret = Read-Host "Client Secret" -AsSecureString |
Microsoft Graph 版でも、受信トレイの最新 10 件が ReceivedDateTime、From、Subject の 3 列で表示されます。

変換前後を並べると、違いは次のようになります。
| 項目 | EWS 版 | Microsoft Graph 版 |
|---|---|---|
| スクリプトのパラメーター | Tenant ID、Client ID、Client Secret、Mailbox | 同じ |
| 取得するメール | 受信トレイの最新 10 件 | 同じ |
| 表示する項目 | 受信日時、差出人表示名、件名 | 同じ |
| トークンの対象 | Office 365 Exchange Online | Microsoft Graph |
| API | EWS の FindItem |
Microsoft Graph の List messages |
| 要求と応答 | SOAP / XML | REST / JSON |
| アプリケーション権限 | full_access_as_app |
Mail.ReadBasic.All |
内部で使う API やデータ形式は変わっています。一方、スクリプトの入力と出力を維持したため、利用者から見た動作はほとんど変わりません。
Copilot に任せる部分と人が確認する部分
今回のような小さな EWS 呼び出しでは、コード変換の多くを Copilot に任せられます。ただし、生成されたコードをそのまま本番で使うのではなく、権限と動作は人が確認します。
| Copilot に任せた部分 | 人が確認すべき部分 |
|---|---|
| トークンの対象リソースと API エンドポイントの変更 | EWS の操作に対応する Microsoft Graph API があること |
| SOAP リクエストから REST リクエストへの変更 | 取得するデータに対して権限が過剰でないこと |
| XML から JSON への応答処理の変更 | 管理者の同意と EWS 権限の失効が完了していること |
| 1 対 1 で対応しない処理の代替案と周辺コードの変更 | 代替方法による動作の違いを許容できること |
| 既存のパラメーターと出力形式の維持 | 変換前後の件数、並び順、表示内容が同等であること |
| JSON から出力オブジェクトへの変換 | 日時のタイム ゾーンや型が変換前後で一致していること |
| エラー処理を含むコードのたたき台の作成 | コードや画面に秘密情報が残っていないこと |
コードのたたき台を短時間で作れることは、Microsoft Graph への移行を始めるうえで大きな助けになります。人が確認すべきポイントを先に押さえておけば、既存の EWS コードを 1 つずつ Microsoft Graph 版へ置き換えていく流れもイメージしやすくなります。
まとめ
EWS の FindItem を使う PowerShell スクリプトを GitHub Copilot に渡し、Microsoft Graph の List messages を使うコードへ変換しました。API の呼び出し方は変わりましたが、パラメーターと出力を維持することで、変換前後の動作はほぼ同じにできました。
今回は読者が手元で簡単に検証できるように PowerShell を使いましたが、この進め方は PowerShell に限定されません。C# など他の言語で作られた EWS アプリでも、Copilot に既存コードを分析させ、EWS の処理を対応する Graph API へ置き換え、権限と変換前後の動作を確認するという同じ流れで移行を進められます。言語によってコードや利用するライブラリは異なりますが、この記事で紹介したプロンプトと確認のポイントは共通して利用できます。
すべてを Copilot に任せるのではなく、API の機能対応、最小権限、管理者の同意、実際の出力を人が確認することがポイントです。既存アプリの小さな EWS 呼び出しを 1 つ選び、同じように変換前後を比べてみると、Microsoft Graph への移行を具体的に始められます。
まずは変換前と同じ動作を確認することが大切ですが、移行は既存の実装や要件を見直すよい機会でもあります。この見直しも、既存コードを Copilot に分析してもらい、改善候補と影響を整理しながら一緒に進めることができます。取得するデータ、処理の流れや頻度、必要な権限が現在も最適かを確認し、認証方法、対象メールボックスの制限、ページング、スロットリング、再試行、監視などを Microsoft Graph を前提に検討すれば、想像しているよりも取り組みやすくなります。
Copilot の提案をそのまま採用するのではなく、業務要件や運用への影響は人が判断する必要があります。それでも、EWS への依存を解消するだけでなく、これからも運用しやすいアプリへ発展させるための最初の一歩を、Copilot と一緒に踏み出すことができます。
参考資料
- EWS アプリを Microsoft Graph に移行する
- List messages
- Microsoft identity platform と OAuth 2.0 クライアント資格情報フロー
- Microsoft Graph のアクセス許可リファレンス: Mail.ReadBasic.All
- エンタープライズ アプリケーションに付与されたアクセス許可を確認して失効する
免責事項
本サンプル コードは、あくまでも説明のためのサンプルとして提供されるものであり、製品の実運用環境で使用されることを前提に提供されるものではありません。 本サンプル コードおよびそれに関連するあらゆる情報は、「現状のまま」で提供されるものであり、商品性や特定の目的への適合性に関する黙示の保証も含め、明示・黙示を問わずいかなる保証も付されるものではありません。 マイクロソフトは、お客様に対し、本サンプル コードを使用および改変するための非排他的かつ無償の権利ならびに本サンプル コードをオブジェクト コードの形式で複製および頒布するための非排他的かつ無償の権利を許諾します。 但し、お客様は、(1) 本サンプル コードが組み込まれたお客様のソフトウェア製品のマーケティングのためにマイクロソフトの会社名、ロゴまたは商標を用いないこと、(2) 本サンプル コードが組み込まれたお客様のソフトウェア製品に有効な著作権表示をすること、および (3) 本サンプル コードの使用または頒布から生じるあらゆる損害 (弁護士費用を含む) に関する請求または訴訟について、マイクロソフトおよびマイクロソフトの取引業者に対し補償し、損害を与えないことに同意するものとします。