DEV Community

bubobo
bubobo

Posted on

Microsoft is retiring EWS in 2026 — how to find every EWS call in your codebase

If your apps talk to Exchange Online over Exchange Web Services (EWS), the clock is ticking. Microsoft is retiring EWS for Exchange Online, with blocking starting October 2026. After that, EWS requests to Exchange Online stop working and you must use the Microsoft Graph API instead. (On-premises Exchange isn't affected the same way.)

The migration itself is well documented. The annoying part is the first step: figuring out where your code actually touches EWS — especially in older or large codebases spread across .NET, Java, Python and PowerShell.

Here's a practical checklist of what to look for, and what each maps to in Microsoft Graph.

What EWS usage looks like

Connection & auth

  • Microsoft.Exchange.WebServices namespace, new ExchangeService(...), ExchangeVersion
  • AutodiscoverUrl(...) — Graph has no Autodiscover; use the fixed endpoint https://graph.microsoft.com/v1.0
  • WebCredentials / basic auth — replaced by OAuth2 via MSAL (delegated or app-only)
  • exchangelib (Python), New-WebServiceProxy (PowerShell), microsoft.exchange.webservices (Java)

Operations → Graph equivalents

EWS Microsoft Graph
FindItems / ItemView GET /me/messages ($filter, $search)
EmailMessage + SendAndSaveCopy POST /me/sendMail
FindFolders / WellKnownFolderName GET /me/mailFolders
Appointment / CalendarFolder /me/events, /me/calendar
GetUserAvailability POST /me/calendar/getSchedule
ContactsFolder /me/contacts
SyncFolderItems delta query GET /me/mailFolders/{id}/messages/delta
StreamingSubscription (pull/push) Graph change notifications (POST /subscriptions) + webhook
EWS impersonation (ImpersonatedUserId) app-only auth + target /users/{id}

A faster way to scan

Grepping by hand works, but it's easy to miss things. I built a small free tool for exactly this: EWScan. Drop in your project as a .zip (or individual files) and it lists every EWS reference — file, line, and the Microsoft Graph replacement for each — so you can scope the migration. It runs entirely in your browser; your source code is never uploaded. (Disclosure: I made it.)

Migration tips

  • Start with auth: set up MSAL + register an app in Entra ID, then port one read path (e.g. list messages) end-to-end before the rest.
  • Prefer application permissions + /users/{id} where you used impersonation.
  • Replace SyncFolderItems polling with delta queries, and EWS subscriptions with Graph change notifications.

Don't wait until October — scan your code, scope the work, and migrate the high-traffic paths first.

Top comments (0)