---
title: "Migrate from EWS to Microsoft Graph API"
description: "Move EWS mailbox automation to Microsoft Graph with a practical inventory, permissions, PowerShell SDK, and cutover validation checklist."
canonical: "https://adamtheautomator.com/migrate-ews-microsoft-graph-api/"
---

# Migrate from EWS to Microsoft Graph API

> Move EWS mailbox automation to Microsoft Graph with a practical inventory, permissions, PowerShell SDK, and cutover validation checklist.

Source: https://adamtheautomator.com/migrate-ews-microsoft-graph-api/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Migrate from EWS to Microsoft Graph API](https://adamtheautomator.com/wp-content/uploads/2026/07/featured_image-4.png)

# Migrate from EWS to Microsoft Graph API

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)8 July 20266 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[API](/tag/api/)[Microsoft 365](/tag/microsoft-365/)[Microsoft Graph](/tag/microsoft-graph/)

Table of Contents

*   [Prerequisites](#prerequisites)
*   [Understanding What Changes When You Leave EWS](#understanding-what-changes-when-you-leave-ews)
*   [Step 1: Inventory Every EWS Dependency](#step-1-inventory-every-ews-dependency)
*   [Step 2: Choose Delegated or Application Permissions](#step-2-choose-delegated-or-application-permissions)
*   [Step 3: Install and Connect the Microsoft Graph PowerShell SDK](#step-3-install-and-connect-the-microsoft-graph-powershell-sdk)
*   [Step 4: Rewrite a Basic Mailbox Read](#step-4-rewrite-a-basic-mailbox-read)
*   [Step 6: Handle Message Trace and Reporting Carefully](#step-6-handle-message-trace-and-reporting-carefully)
*   [Step 7: Build a Validation Checklist](#step-7-build-a-validation-checklist)
*   [Common Migration Pitfalls](#common-migration-pitfalls)
*   [Wrapping Up](#wrapping-up)

Microsoft 365 automation that still depends on Exchange Web Services (EWS) needs a plan. EWS has been the dependable workhorse for mailbox automation for years, but Microsoft now points Exchange Online developers and administrators toward Microsoft Graph for modern mail, calendar, user, and group access.

If you own an old PowerShell script, help desk tool, calendar integration, or background service that talks to `/EWS/Exchange.asmx`, this tutorial walks you through a practical migration path. You will inventory what the EWS workload does, map each operation to Microsoft Graph, set up the Microsoft Graph PowerShell SDK, and test the common mailbox and calendar patterns most teams need first.

## Prerequisites

To follow along, you will need:

*   A Microsoft 365 tenant with Exchange Online.
    
*   A test mailbox you are allowed to query.
    
*   PowerShell 7 or Windows PowerShell 5.1.
    
*   Permission to use or request Microsoft Graph permissions in Microsoft Entra ID.
    
*   Basic familiarity with EWS concepts such as `ExchangeService`, Autodiscover, impersonation, and EWS operation names.
    

> \[!NOTE\]
> 
> The examples below are safe patterns, but Graph calls that read real mailbox data require tenant authentication and consent. Run them in a test tenant or against a non-production mailbox first.

## Understanding What Changes When You Leave EWS

EWS and Microsoft Graph solve similar business problems, but they do it with different shapes.

[EWS is a SOAP-based API](https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/ews-applications-and-the-exchange-architecture) that sends XML over HTTP/S to Exchange. EWS applications commonly use the EWS Managed API, `ExchangeService`, Autodiscover, impersonation, and operation names such as `FindItem`, `GetItem`, `CreateItem`, and `UpdateItem`.

[Microsoft Graph](https://learn.microsoft.com/en-us/graph/use-the-api) is a REST API. Instead of building SOAP envelopes, you call resources such as users, messages, mail folders, and events. Authentication and authorization move through Microsoft Entra ID and OAuth, using delegated or application permissions.

That shift means you should not treat the migration as a simple endpoint replacement. A better approach is to map behavior:

| EWS concept | Microsoft Graph concept |
| --- | --- |
| `ExchangeService` client object | Graph SDK client or REST call to `https://graph.microsoft.com` |
| SOAP XML request | REST request with JSON response |
| Autodiscover endpoint resolution | Graph resource paths such as `/users/{id}/messages` |
| EWS impersonation | Delegated permissions, application permissions, and access policies |
| `FindItem` and `GetItem` | List and get message/event endpoints |
| EWS subscriptions | Graph change notifications or delta queries |

Microsoft publishes an [EWS-to-Graph API mapping reference](https://learn.microsoft.com/en-us/graph/migrate-exchange-web-services-api-mapping), and that page should become part of your migration workbook.

## Step 1: Inventory Every EWS Dependency

Start with discovery. Before rewriting code, find every place your environment uses EWS. Search source control, scheduled task servers, automation accounts, config files, and vendor integration settings.

Look for common EWS markers:

```powershell
Select-String -Path .\* -Recurse -Pattern \
    'ExchangeService','Microsoft.Exchange.WebServices','EWS/Exchange.asmx','FindItem','GetItem','AutodiscoverUrl'
```

> \[!TIP\]
> 
> Include configuration files in the search, not just source code. Many legacy jobs store the EWS URL or service account in a JSON, XML, INI, or scheduled task export.

For each hit, capture the following details in a spreadsheet or issue tracker:

| Field | Why it matters |
| --- | --- |
| Application or script name | Gives you an owner and migration scope |
| EWS operations used | Drives the Graph endpoint mapping |
| Authentication method | Determines delegated vs. application permission design |
| Mailboxes touched | Helps limit permission scope |
| Business process | Helps prioritize cutover order |
| Schedule or trigger | Identifies outage windows and rollback needs |
| Output dependencies | Shows reports, files, or downstream systems to validate |

This step is not glamorous, but it prevents the common migration failure: rewriting the visible script while missing the scheduled task that runs once a month.

## Step 2: Choose Delegated or Application Permissions

Graph permissions are where many EWS migrations slow down. EWS-era code often assumes a service account can reach many mailboxes. Graph makes you describe that access through permissions and admin consent.

Use **delegated permissions** when the automation runs as a signed-in user and should only do what that user can do. This model fits help desk tools, interactive scripts, and user-driven mailbox utilities.

Use **application permissions** when a background service runs without a signed-in user. This model fits daemons, nightly jobs, and integrations. Application permissions are powerful, so do not approve broad tenant-wide access unless the workload truly needs it.

For mail workloads, Microsoft explains that Graph can access Outlook mail with the appropriate [delegated or application mail permissions](https://learn.microsoft.com/en-us/graph/api/resources/mail-api-overview?view=graph-rest-1.0). Your security review should answer three questions before code is written:

1.  Which mailbox data does the app need?
    
2.  Is the app acting as a user or as itself?
    
3.  Can access be limited to a mailbox group, test mailbox, or application access policy?
    

> \[!WARNING\]
> 
> Do not grant `Mail.ReadWrite` or broad application permissions just to make the first proof of concept work. Start with read-only permissions, test the smallest scenario, and expand only when the migration requires it.

## Step 3: Install and Connect the Microsoft Graph PowerShell SDK

The Microsoft Graph PowerShell SDK is a good bridge for administrators because it lets you test Graph behavior before you rewrite full applications.

Install the SDK from the [PowerShell Gallery](https://www.powershellgallery.com/packages/Microsoft.Graph):

```powershell
Install-Module Microsoft.Graph -Scope CurrentUser
```

Connect with the scopes you need for a basic mail read test:

```powershell
Connect-MgGraph -Scopes 'User.Read','Mail.Read','Calendars.Read'
```

Check your context after signing in:

```powershell
Get-MgContext | Select-Object Account, TenantId, Scopes
```

If your tenant requires admin consent for these scopes, the connection step will not complete until an administrator approves the permissions.

## Step 4: Rewrite a Basic Mailbox Read

Many EWS scripts start by finding recent messages. In EWS, that usually means `FindItem` against a folder. In Graph PowerShell, start with `Get-MgUserMessage`.

```powershell
$userId = 'sharedmailbox@contoso.com'

Get-MgUserMessage -UserId $userId -Top 10 -Property 'id,subject,receivedDateTime,from' |
    Select-Object Subject, ReceivedDateTime, @{Name='From';Expression={$_.From.EmailAddress.Address}}
```

The equivalent REST shape is easy to understand:

“\`plain text  
GET https://graph.microsoft.com/v1.0/users/sharedmailbox@contoso.com/messages?$top=10&$select=id,subject,receivedDateTime,from

```
Notice two important differences from EWS:

- You request JSON properties with `$select` instead of binding to strongly typed EWS properties.

- The message ID you receive is a Graph resource ID. Do not assume it matches an EWS ID stored in an old database.

## Step 5: Rewrite Calendar Reads

Calendar integrations are another common EWS dependency. Graph exposes calendar and event resources directly.

Use the SDK to list upcoming events:
```

$userId = ‘sharedmailbox@contoso.com’  
$start = (Get-Date).ToUniversalTime().ToString(‘o’)  
$end = (Get-Date).AddDays(7).ToUniversalTime().ToString(‘o’)

Get-MgUserCalendarView -UserId $userId -StartDateTime $start -EndDateTime $end |  
Select-Object Subject, Start, End, Organizer

````
For REST-based applications, the same idea targets the calendar view endpoint:

```plain text
GET https://graph.microsoft.com/v1.0/users/sharedmailbox@contoso.com/calendarView?startDateTime=2026-07-05T00:00:00Z&endDateTime=2026-07-12T00:00:00Z
````

This is where you should validate time zones, recurrence behavior, and organizer fields. Calendar bugs are easy to miss if you only test one simple meeting.

## Step 6: Handle Message Trace and Reporting Carefully

Not every Exchange admin task has a clean one-for-one Graph replacement. For example, message trace and some reporting workflows are often better handled through Exchange Online PowerShell cmdlets rather than Graph mail endpoints.

If your EWS-era process mixes mailbox item access with Exchange reporting, split it into two workstreams:

*   Use Microsoft Graph for mailbox, user, group, and calendar operations that Graph supports.
    
*   Use Exchange Online PowerShell for Exchange admin reporting and transport-related tasks that remain in the Exchange management plane.
    

That split keeps your migration honest. The goal is not to force every Exchange task through Graph; the goal is to remove unsupported EWS dependencies without breaking the business workflow.

## Step 7: Build a Validation Checklist

Before cutover, validate the migration with the people who own the process, not just the code.

Use this checklist:

*   Confirm every EWS operation has a Graph, Exchange Online PowerShell, or documented replacement path.
    
*   Confirm permissions are least-privilege and approved.
    
*   Test with a normal mailbox, shared mailbox, and any special mailbox type the workload supports.
    
*   Compare old and new output for the same time window.
    
*   Test throttling and retry behavior.
    
*   Log request IDs and errors so support can troubleshoot failures.
    
*   Keep the old job disabled but recoverable during the first production run.
    

A simple comparison harness can help during parallel testing:

```powershell
$userId = 'sharedmailbox@contoso.com'
$outputPath = '.\graph-mail-sample.csv'

Get-MgUserMessage -UserId $userId -Top 25 -Property 'subject,receivedDateTime,from' |
    Select-Object Subject, ReceivedDateTime, @{Name='From';Expression={$_.From.EmailAddress.Address}} |
    Export-Csv -Path $outputPath -NoTypeInformation

Write-Host "Graph sample exported to $outputPath"
```

> \[!NOTE\]
> 
> Keep one exported sample from the old EWS job and one exported sample from the new Graph job. Ask the business owner to review the fields, not just the developer who wrote the script.

## Common Migration Pitfalls

Avoid these traps as you work through the migration:

*   **Assuming EWS and Graph IDs are interchangeable.** Store new Graph IDs separately and plan any lookup migration.
    
*   **Skipping consent review.** A working script with excessive permissions creates a security problem.
    
*   **Ignoring shared mailboxes.** Validate shared mailbox access early because it exposes permission design issues.
    
*   **Testing only happy-path messages.** Include attachments, meetings, recurring events, and large folders.
    
*   **Forgetting non-code dependencies.** Scheduled tasks, vendor connectors, and runbooks often hide EWS URLs in configuration files.
    

## Wrapping Up

Migrating from EWS to Microsoft Graph API is a manageable project when you treat it as a workflow migration. Inventory the old EWS behavior, map each operation, choose the right permission model, and prove the replacement with Graph PowerShell before rewriting production code.

The biggest mindset shift is moving from a service-account SOAP model to a permissioned REST model. Once you make that shift explicit, your migration plan becomes clearer: small tests, least-privilege permissions, side-by-side validation, and a controlled cutover.

Your next step is to pick one low-risk EWS script, map its operations against Microsoft’s EWS-to-Graph reference, and produce the same output with Microsoft Graph PowerShell. Once that works, you have a repeatable pattern for the rest of your EWS estate.

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fmigrate-ews-microsoft-graph-api%2F&text=Migrate%20from%20EWS%20to%20Microsoft%20Graph%20API)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fmigrate-ews-microsoft-graph-api%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fmigrate-ews-microsoft-graph-api%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2022/08/Go-Behind-The-Scenes-with-a-Postman-Install-and-How-To-Guide.jpg)

### [Go Behind The Scenes with a Postman Install and How-To Guide](/postman-install/)

Learn how to perform a Postman install on Windows & Linux in this how-to guide for API management in this ATA Learning tutorial!

![](https://adamtheautomator.com/wp-content/uploads/2026/06/featured_image-13.png)

### [Taming AI Tool Sprawl: A PowerShell Guide to Auditing and Governing Unauthorized AI Applications](/taming-ai-tool-sprawl-powershell-guide-auditing/)

Detect and govern unauthorized AI tools with PowerShell, Microsoft Graph, Entra ID, and Defender for Cloud Apps.

![](https://adamtheautomator.com/wp-content/uploads/publisher/2e05d9c85b2b8184bb24f8beaeb7f165/85751120c0fb4909afa44fc19e072a60152e0de73a44e1bba3c2dc4f2c71b424.webp)

### [SQL Server 2025 Upgrades: Avoid These Breaking Changes](/sql-server-upgrade-breaking-changes/)

Avoid SQL Server 2025 upgrade failures. Master the breaking changes in encryption, TDS, and replication before you plan your migration.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
