Guide
EWS to Microsoft Graph Migration: Developer Guide
Microsoft blocks EWS for Exchange Online on October 1, 2026, and permanently removes it on April 1, 2027. This guide covers the full timeline, auth model changes (NTLM to OAuth 2.0), feature parity gaps, and three migration paths. Includes code examples for Graph API and a provider-agnostic alternative. Works with Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP.
By Caleb Geene
The deprecation timeline
Microsoft announced EWS retirement in September 2023 and has been tightening the schedule since. According to Microsoft's official deprecation page, here are the dates that matter:
| Date | What happens |
|---|---|
| July 1, 2026 | F1, F3, and Kiosk licenses start returning HTTP 403 for EWS |
| August 2026 | Deadline to configure AppID AllowList for temporary exemption |
| October 1, 2026 | EWS blocked for all non-Microsoft apps without AllowList |
| April 1, 2027 | EWS permanently removed. No re-enablement, no exceptions |
If you do nothing, your EWS-based code returns errors starting October 2026. The TechCommunity announcement confirms that Microsoft will set EWSEnabled=False on tenants that haven't opted in.
On-premises Exchange: not affected
EWS on Exchange Server 2016 and 2019 is not deprecated. On-prem mailboxes continue to use EWS with no changes. This creates a split for hybrid deployments: cloud mailboxes must use Graph, on-prem mailboxes still use EWS. If you maintain both, you need two codepaths -- or an abstraction that handles the routing.
Auth model: NTLM/Basic to OAuth 2.0
EWS traditionally used NTLM, Kerberos, or Basic Auth. Graph API requires OAuth 2.0 with Azure AD (Entra ID) app registrations. The migration means:
- Register an Azure AD app with Mail.Read, Mail.Send, Calendars.ReadWrite, or other scopes
- Choose a flow: authorization code (delegated) for user context, client credentials (application) for daemon/service apps
- Handle token lifecycle: access tokens expire in 60-90 minutes, refresh tokens in 90 days
- Admin consent: application-level permissions need tenant admin approval
# EWS (old) - Basic Auth or NTLM
$cred = Get-Credential
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
$service.Credentials = $cred
$service.Url = "https://outlook.office365.com/EWS/Exchange.asmx"
# Graph API (new) - OAuth 2.0 with MSAL
Connect-MgGraph -Scopes "Mail.Read","Mail.Send"
$messages = Get-MgUserMessage -UserId "me" -Top 10Feature parity gaps (as of April 2026)
Graph API covers most EWS scenarios, but gaps remain:
| EWS Feature | Graph API Status |
|---|---|
| Archive mailbox access | Not available |
| Public folder CRUD | Not planned -- restricted to Outlook clients only |
| Mailbox import/export | Not available |
| Recurring event delta queries | Partial support |
| User configuration (dictionary items) | Covered by Exchange Admin API (preview) |
| Extended properties (custom MAPI props) | Supported via singleValueExtendedProperties |
| Autodiscover | Not needed -- Graph uses a single endpoint |
| Mail read/send/search | Full parity |
| Calendar events CRUD | Full parity |
| Contacts CRUD | Full parity |
Microsoft released the Exchange Admin API as a temporary bridge for some gaps. But there's no firm date for when all parity gaps close.
Three migration paths
Path 1: Migrate to Microsoft Graph API
The official path. Replace every EWS call with its Graph equivalent. Microsoft provides an EWS code analyzer that scans your codebase and maps EWS operations to Graph API equivalents.
# EWS: Find emails by subject
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(50)
$filter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring(
[Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject, "invoice")
$results = $service.FindItems(
[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox, $filter, $view)
# Graph: Same operation
$messages = Get-MgUserMessage -UserId "me" -Filter "contains(subject, 'invoice')" -Top 50Pros: Stays within the Microsoft ecosystem, access to newest features. Cons: Azure AD app registration, OAuth token management, no support for non-Microsoft providers, feature parity gaps.
Path 2: Temporary AppID AllowList
Buys time until April 2027. Register your app's ID in the tenant's EWS AllowList before August 2026:
# Check current EWS settings
Get-OrganizationConfig | Select-Object EwsEnabled, EwsAllowList
# Add your app to the AllowList
Set-OrganizationConfig -EwsAllowList @{Add="your-app-client-id"}
Set-OrganizationConfig -EwsEnabled $truePros: No code changes needed immediately. Cons: Only delays the problem by 6 months. EWS is permanently removed April 1, 2027.
Path 3: Use a unified abstraction
Instead of migrating from one Microsoft-specific protocol to another, use a tool that abstracts away the provider layer entirely. Nylas CLI connects to Exchange Online, on-prem Exchange, Gmail, Outlook, Yahoo, iCloud, and IMAP through one interface:
# Install
brew install nylas/nylas-cli/nylas
# Authenticate (handles OAuth, EWS, Graph internally)
nylas auth config
# Read email -- works regardless of whether the mailbox is
# Exchange Online (Graph), Exchange on-prem (EWS), or Gmail
nylas email list --limit 10
# Search
nylas email search "invoice" --limit 50
# Send
nylas email send \
--to "colleague@company.com" \
--subject "Report" \
--body "Attached." \
--attach ./report.pdfPros: No protocol-specific code, no Azure AD app registration, works across all providers, on-prem and cloud through one interface. Cons: External dependency. Requires Nylas API key.
Side-by-side comparison
| Concern | EWS (retiring) | Graph API | Nylas CLI |
|---|---|---|---|
| Auth | NTLM / Basic / OAuth | OAuth 2.0 only | One-time nylas auth config |
| Azure AD app required | No (Basic) / Yes (OAuth) | Yes | No |
| On-prem Exchange | Supported | Not supported | Supported (via EWS internally) |
| Exchange Online | Blocked Oct 2026 | Supported | Supported (via Graph internally) |
| Gmail, Yahoo, iCloud | Not supported | Not supported | Supported |
| Token management | Manual | Manual (MSAL) | Automatic |
| Code changes needed | N/A (retiring) | Full rewrite from EWS | One-time migration |
Hybrid Exchange: the dual-codebase problem
Many organizations run hybrid Exchange -- some mailboxes in Exchange Online, some on-prem. After October 2026, cloud mailboxes need Graph API while on-prem mailboxes still need EWS. Microsoft Graph doesn't support on-prem Exchange Server at all.
This forces two authentication flows, two API surfaces, and two sets of error handling in the same application. The Nylas platform handles this routing internally -- it detects whether a mailbox is cloud or on-prem and uses the appropriate protocol.
Migration checklist
- Audit your EWS usage -- Run Microsoft's EWS code analyzer to inventory every EWS call
- Check for parity gaps -- Compare your EWS operations against the feature gap table above
- Register your app before August 2026 -- If you need more time, add your app to the AllowList
- Test with F1/F3 licenses first -- These were blocked in March 2026, so they're already on the new behavior
- Plan for hybrid -- If you have on-prem Exchange, decide how to handle the dual-protocol split
- Monitor Microsoft's updates -- Feature parity gaps are closing quarterly
Frequently asked questions
When is EWS being retired for Exchange Online?
Microsoft blocks EWS requests from non-Microsoft apps starting October 1, 2026. Tenants that configure an AppID AllowList before August 2026 get a temporary exemption. All EWS access is permanently removed on April 1, 2027.
Is EWS deprecated for on-premises Exchange Server?
No. EWS remains fully supported for Exchange Server 2016 and 2019. The deprecation only affects Exchange Online (Microsoft 365).
What EWS features are missing from Graph API?
As of April 2026, Graph API lacks archive mailbox access, public folder CRUD, mailbox import/export, and full recurring event delta support. Microsoft is closing gaps quarterly but hasn't committed to a date for full parity.
Can I skip the migration entirely?
Yes, if you use an abstraction layer. The Nylas platform connects to Exchange Online, on-prem Exchange, and 4 other providers through a single interface. Provider-side deprecations don't require code changes on your end.
Next steps
- List Exchange emails from the CLI -- read and search Exchange mailboxes without EWS or Graph
- Manage Exchange calendar from the CLI -- create, update, and delete events
- Replace Send-MgUserMessage -- migrate from Graph PowerShell cmdlets
- Manage Office 365 email from PowerShell -- read, search, and organize your M365 inbox
- Send email from the terminal -- the cross-provider email sending guide
- Full command reference -- every flag and subcommand documented