Why the last server is worth the effort
An on-premises Exchange server is connected to the internet, holds far-reaching rights in Active Directory and has been the target of several critical attacks in recent years. As long as it runs, it has to be patched, monitored and certified. Exchange Server 2016 and 2019 have been out of support since 14 October 2025. If the server only exists for administration and relay, the choice is between moving to Exchange Server SE, with subscription licensing, or switching it off.
Since Exchange Server 2019 CU12, Microsoft supports managing synchronised recipients with the Exchange Management Tools, without a running Exchange server. The prerequisites are clear:
- no mailboxes left on-premises, including shared mailboxes and resource mailboxes
- no mail flow and no relay through the server
- no hybrid features you still need, such as on-premises public folders or cross-premises free/busy
- Active Directory stays the source of authority, synchronised with Entra Connect
The order of work follows from that list: find the senders, move them, settle recipient management, clean up hybrid and DNS, then switch off.
Step 1: find everything that still sends through the server
This is where the projects stall. Scanners, line-of-business applications, monitoring, a backup appliance, a script on a file server: they all send to the Exchange server by IP or by name, often anonymously through a receive connector. Nobody documented them, because it just worked.
# Receive connectors: who may connect, and how
Get-ReceiveConnector | Format-Table Name, Bindings, RemoteIPRanges, PermissionGroups, AuthMechanism -AutoSize
# Turn on protocol logging for a few weeks
Get-ReceiveConnector | Set-ReceiveConnector -ProtocolLoggingLevel Verbose
# Which client IPs delivered mail by SMTP in the last 14 days
Get-TransportService | Get-MessageTrackingLog -Start (Get-Date).AddDays(-14) -EventId RECEIVE -ResultSize Unlimited |
Where-Object { $_.Source -eq "SMTP" } |
Group-Object OriginalClientIp | Sort-Object Count -Descending | Select-Object Count, Name
The protocol logs are under TransportRoles\Logs\FrontEnd\ProtocolLog\SmtpReceive in the Exchange installation path. Let them run long enough to catch the monthly and quarterly senders: payroll runs, statements, end-of-month reports. Turn every IP into a row in a table with system, sender address, owner and target path.
A typical pattern: the decommissioning date is set, and in the last week several multifunction devices and two applications turn up that send anonymously through a receive connector. The fix is always the same: inventory, re-route, observe, then switch off. Finding them a month earlier is cheaper.
Step 2: give every sender a new path
| Sender | Target path | Notes |
|---|---|---|
| Your own scripts and applications | Microsoft Graph sendMail with an app registration and a certificate | Scope the app to the sending mailboxes with RBAC for Applications |
| Applications that support OAuth for SMTP | SMTP AUTH with OAuth against Exchange Online | No passwords in config files |
| Devices at a site with a static IP | Connector relay to your tenant's MX endpoint | Inbound connector restricted by IP or certificate; IP in SPF |
| Devices that only speak plain SMTP | A small local SMTP-to-Graph bridge | Accepts only internal networks and allowed senders |
| Internal bulk mail | High Volume Email in Exchange Online | Internal recipients only |
For Graph, the important part is the scope. The application permission Mail.Send granted in Entra ID allows sending as any mailbox in the tenant. Grant it in Exchange Online instead, limited to the mailboxes that send:
Connect-ExchangeOnline
New-ServicePrincipal -AppId "<application id>" -ObjectId "<enterprise app object id>" -DisplayName "Graph mail relay"
New-ManagementScope -Name "Scope-GraphMailRelay" -RecipientRestrictionFilter "CustomAttribute10 -eq 'GraphMailSend'"
Set-Mailbox -Identity "scanner@example.com" -CustomAttribute10 "GraphMailSend"
New-ManagementRoleAssignment -App "<enterprise app object id>" -Role "Application Mail.Send" -CustomResourceScope "Scope-GraphMailRelay"
Test-ServicePrincipalAuthorization -Identity "<enterprise app object id>" -Resource "scanner@example.com"
Do not also grant Mail.Send with admin consent in Entra ID. Permissions from both places add up, and the tenant-wide grant overrides the scope. More on this in App registrations with least privilege.
Step 3: settle recipient management
With directory synchronisation, Active Directory is the source of authority for synchronised users. Their Exchange attributes, such as proxyAddresses, targetAddress and mail, cannot be changed in Exchange Online. Without a supported tool, people start editing them in ADSI Edit or the attribute editor, and that is how routing breaks.
The Management Tools from Exchange Server 2019 CU12 or later solve this. Install them on a domain-joined management machine, grant the permissions with the script Microsoft ships for it, and use the recipient management snap-in:
# On the management machine, from the Exchange 2019 CU12+ (or SE) media
.\Setup.exe /IAcceptExchangeServerLicenseTerms_DiagnosticDataOFF /Role:ManagementTools
# Once, with sufficient AD rights: the script from the Exchange "Scripts" folder
.\Add-PermissionForEMT.ps1
# Day to day
Add-PSSnapin *RecipientManagement
New-RemoteMailbox -Name "Ana Lim" -UserPrincipalName ana.lim@example.com -OnPremisesOrganizationalUnit "OU=Staff,DC=example,DC=local"
Set-RemoteMailbox -Identity ana.lim@example.com -EmailAddresses @{Add="smtp:a.lim@example.com"}
Test creating, changing and removing a remote mailbox before the server goes away, and write the procedure into the help desk runbook. Check the exact setup syntax against the documentation of the CU you install.
Step 4: clean up hybrid, DNS and the network
- Autodiscover: the public record points to
autodiscover.outlook.com. Internally, Outlook on domain-joined machines may still find the server through the service connection point in Active Directory. Clear it before shutdown, for example withSet-ClientAccessService -Identity <server> -AutoDiscoverServiceInternalUri $null. - Connectors: the inbound and outbound connectors the Hybrid Configuration Wizard created in Exchange Online are no longer needed once nothing routes on-premises. Disable them first, watch for a week, then remove them.
- DNS: remove host records that point to the server, and remove its public IP from SPF once nothing sends from it.
- Firewall and certificates: close the inbound SMTP and HTTPS rules, and let the server certificate expire instead of renewing it.
- Other dependencies: applications using EWS against the on-premises server, monitoring checks, backup jobs.
Step 5: switch off, and keep a way back
Shut the server down rather than removing it straight away, and leave it off for an agreed period. If something breaks, starting it again is the rollback. Microsoft's guidance for the Management Tools scenario is to shut the last server down permanently; check the current documentation before you uninstall anything, because the Exchange organisation in Active Directory has to stay.
Checklist
- No mailboxes on-premises, including shared and resource mailboxes
- Protocol logging on for several weeks, every sending IP assigned to a system and an owner
- Every sender moved: Graph, SMTP with OAuth, connector, bridge or High Volume Email
- Graph senders scoped with RBAC for Applications, tested with
Test-ServicePrincipalAuthorization - Management Tools installed, permissions granted, remote mailbox procedures tested and documented
- Autodiscover SCP cleared, hybrid connectors disabled and observed
- DNS, SPF, firewall rules and certificates cleaned up
- Server shut down for an agreed period before final removal