As Microsoft executes its tenant-by-tenant phased shutdown of Exchange Web Services (EWS) in Exchange Online, enterprise organizations face an urgent deadline: migrating custom line-of-business applications, mail archiving utilities, and third-party migration tools to Microsoft Graph or the Exchange Online Admin API.
However, if an essential production integration is caught off-guard when Microsoft disables EWS in your tenant, you do not have to endure prolonged downtime while rewriting your codebase.
Microsoft provides an official tenant-level override parameter: EwsAllowedAppIDs. By registering authorized Microsoft Entra Application (Client) IDs in your Exchange organization configuration, you can carve out emergency exceptions that allow specific token-authenticated apps to continue using EWS while you finalize their Graph migration.
In this runbook, we show you how to audit active EWS applications, configure EwsAllowedAppIDs safely without overwriting existing entries, and manage replication delays.
The Modern EWS Security Architecture
Historically, Exchange administrators controlled EWS access using User-Agent string filtering (EwsApplicationAccessPolicy with EwsAllowList or EwsBlockList).
In modern cloud environments, User-Agent strings are insecure and easily spoofed. EwsAllowedAppIDs replaces User-Agent filtering with cryptographic token inspection:
- Target:
https://outlook.office365.com/EWS/Exchange.asmx - Bearer OAuth Token issued by Entra ID
- Token claim contains
appid/azp
- Is EWS disabled for this tenant? YES
- Does token
appidmatchEwsAllowedAppIDs?
- Match found: EWS request executes successfully
- No match: Rejected with
403 Forbidden
Step 1: Identify Active EWS Applications Before Whitelisting
To find the exact Microsoft Entra Application (Client) IDs being used by your apps, inspect your Entra Sign-in Logs:
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "AuditLog.Read.All"
# Query service principal and user sign-ins targeting the Office 365 Exchange Online resource
$appSignIns = Get-MgAuditLogSignIn -Filter "resourceDisplayName eq 'Office 365 Exchange Online'" -Top 100
$appSignIns | Where-Object { $_.ClientAppUsed -match "Exchange Web Services|EWS" } |
Select-Object CreatedDateTime, AppDisplayName, AppId, UserPrincipalName, IPAddress |
Format-Table -AutoSize
Note down the AppId GUID (e.g., c841ae33-4093-4385-8a90-6a530761f9b9) for each application requiring an emergency extension.
Step 2: Check Current EWS Organization Settings
Connect to Exchange Online PowerShell:
Connect-ExchangeOnline -UserPrincipalName [email protected]
Crucial Tip: RunningGet-OrganizationConfigby itself will not display the configured application IDs. You must pass the-RetrieveEwsOperationAccessPolicyswitch to query the active policy:
Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy |
Select-Object EwsEnabled, EwsApplicationAccessPolicy, EwsAllowedAppIDs
If EwsAllowedAppIDs is empty, no application-level whitelist has been enforced yet.
Step 3: Safely Configure EwsAllowedAppIDs
Warning — Overwrite Gotcha: Setting -EwsAllowedAppIDs completely replaces the existing array. If you pass a single App ID without including previous entries, all previously whitelisted applications will immediately lose access.
Use this safe PowerShell script to retrieve the existing list, append your new Application ID, and write the updated array back:
function Add-EwsAllowedAppId {
[CmdletBinding(SupportsShouldProcess = $true)]
param (
[Parameter(Mandatory = $true)]
[guid]$ApplicationId
)
# 1. Fetch current list
$currentConfig = Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy
$existingAppIds = @($currentConfig.EwsAllowedAppIDs)
if ($existingAppIds -contains $ApplicationId.ToString()) {
Write-Host "[!] Application ID $ApplicationId is already whitelisted." -ForegroundColor Yellow
return
}
# 2. Append new ID
$updatedAppIds = $existingAppIds + $ApplicationId.ToString()
$formattedList = ($updatedAppIds | Where-Object { $_ }) -join ","
# 3. Apply safely
if ($PSCmdlet.ShouldProcess("OrganizationConfig", "Update EwsAllowedAppIDs with ($formattedList)")) {
Set-OrganizationConfig -EwsAllowedAppIDs $formattedList
Write-Host "[+] Successfully added $ApplicationId to EwsAllowedAppIDs!" -ForegroundColor Green
}
}
# Example Usage:
# Add-EwsAllowedAppId -ApplicationId "c841ae33-4093-4385-8a90-6a530761f9b9"
Step 4: Manage Propagation & Replication Delays
- Directory Cache Delay: Changes made to
Set-OrganizationConfigin Exchange Online replicate across Microsoft’s worldwide datacenters asynchronously. - Timeline: Expect changes to take between 30 minutes and up to 24 hours to take full effect across all mailbox frontend servers.
- Client App Token Refresh: Client applications authenticate using JWT access tokens. If an application holds an active access token issued prior to the policy update, instruct the application service to restart or acquire a fresh token.
How to Clear or Remove Whitelisted Apps
When an application completes its migration to Microsoft Graph, remove its App ID from the whitelist:
# Remove a specific App ID
$targetAppId = "c841ae33-4093-4385-8a90-6a530761f9b9"
$current = (Get-OrganizationConfig -RetrieveEwsOperationAccessPolicy).EwsAllowedAppIDs
$remaining = $current | Where-Object { $_ -ne $targetAppId }
if ($remaining) {
Set-OrganizationConfig -EwsAllowedAppIDs ($remaining -join ",")
} else {
Set-OrganizationConfig -EwsAllowedAppIDs $null
}
Summary Checklist for EWS Retirement Compliance
| Phase | Action Item | Status |
|---|---|---|
| Discovery | Audit Entra ID sign-in logs for resourceDisplayName eq 'Office 365 Exchange Online' | ☐ |
| Emergency Exception | Add mission-critical App IDs to Set-OrganizationConfig -EwsAllowedAppIDs | ☐ |
| Code Modernization | Replace EWS SOAP calls with Microsoft Graph API endpoints (/v1.0/users/{id}/messages) | ☐ |
| Decommissioning | Strip App IDs from EwsAllowedAppIDs and verify that legacy permissions are removed | ☐ |