Microsoft 365

IMAP to Exchange Online migration from cPanel and other hosts

Move mailboxes from cPanel or any IMAP host to Exchange Online with migration batches: CSV prep, endpoint, PowerShell, MX cutover and the cPanel email routing setting that catches people out.

13 min read
On this page

To migrate mail from cPanel or any other IMAP host to Exchange Online, you create licensed Microsoft 365 mailboxes, build a CSV file listing each mailbox and its IMAP credentials, create an IMAP migration endpoint that points at the old mail server, and run a migration batch from the Exchange admin center or Exchange Online PowerShell. The batch copies mail folders and keeps them in sync once a day until you switch the MX record to Microsoft 365 and delete the batch. Only email moves; contacts, calendars and tasks have to be handled separately.

Who this is for and what you will have

This guide is for administrators moving a small or mid-sized organization off shared web hosting (cPanel, Plesk or a similar control panel) or any other IMAP-only mail service into Exchange Online. By the end you will have:

  • Every mailbox's mail folders copied into Exchange Online.
  • New mail flowing to Microsoft 365 through an updated MX record.
  • The hosting account set so it no longer intercepts mail for your domain.
  • A clean stop to synchronization, with nothing lost in the gap.

If you are coming from Google Workspace instead, use the native Gmail migration covered in the Google Workspace to Microsoft 365 migration guide, which also moves calendars and contacts. Once mail is in Exchange Online, the Exchange Online mail flow rules guide covers disclaimers and external sender warnings.

What an IMAP migration does and does not move

ItemMigrated?Notes
Inbox and mail foldersYesNewest items first, up to 500,000 items per mailbox
Messages over 35 MBNoAsk users to save large attachments elsewhere first
Folders with "/" in the nameNoRename them before the migration
ContactsNoExport and import separately
Calendar items and tasksNoExport and import separately
Folders you excludeNoUse the filtering options or ExcludeFolders

Microsoft also notes that the migration service is unaware of messaging records management (MRM) and archive policies. Items that such a policy moves or deletes during the migration are reported as missing, which hides real data loss. Microsoft strongly recommends disabling MRM and archive policies on the target mailboxes until the migration is complete.

Prerequisites

On the Microsoft 365 side

  1. Add and verify your domain in the Microsoft 365 admin center under Settings > Domains before you create users, so mailboxes get addresses in your domain from the start. Do not change the MX record yet.
  2. Create every user and assign a licence that includes Exchange Online. IMAP migration copies data into existing mailboxes; it does not create them.
  3. Get the right permissions. Microsoft's IMAP migration guide points to the "Migration" entry in its recipients permissions article, which lists the Organization Management and Recipient Management role groups.
  4. Install and connect Exchange Online PowerShell if you want to script the migration:
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com

On the hosting side

  1. Find the IMAP server name. In cPanel, go to Email > Email Accounts and select Connect Devices for a mailbox, which opens the Set Up Mail Client page. The Mail Client Manual Settings section lists the incoming server and ports. cPanel recommends its Secure SSL/TLS Settings, with IMAP on port 993; the non-SSL IMAP port is 143. Under the SSL settings, cPanel shows a name in your domain (such as mail.contoso.com) only if the domain has a valid SSL certificate; otherwise it shows the server's own hostname. Use exactly the incoming server name shown for the SSL settings. On other hosts, find the IMAP server name in the provider's mail client settings.
  2. Check connection limits. Firewalls and mail servers often limit total connections, connections per user and connections per IP address. Microsoft recommends raising these before you migrate. On shared hosting you might not be able to change them, which mainly affects speed and how many mailboxes you can migrate in parallel.
  3. Lower the MX record TTL to 3,600 seconds (one hour) or less before you start, on every MX record for the domain. When you switch the MX record later, the change spreads faster. Exchange Online only supports MX TTL values below six hours (21,600 seconds).
  4. Ask users to clean up: delete mail they don't need, rename folders that contain a forward slash, and save very large messages.

Step 1: Build the migration CSV file

The CSV file needs three columns with these exact headers and no spaces:

ColumnContents
EmailAddressThe user's Microsoft 365 mailbox address (the username in Users > Active users)
UserNameThe sign-in name on the IMAP server
PasswordThe password for that sign-in name

cPanel mailboxes sign in with the full email address, so when the domain is the same on both sides the first two columns are identical:

EmailAddress,UserName,Password
alex@contoso.com,alex@contoso.com,TempPassw0rd!1
megan@contoso.com,megan@contoso.com,TempPassw0rd!2
info@contoso.com,info@contoso.com,TempPassw0rd!3

A single file can list up to 50,000 mailboxes and be up to 10 MB, but you don't have to migrate everyone at once. Split users into batches if you want to test with a few mailboxes first.

Choosing which credentials to use

You have three options, in order of how disruptive they are:

  • Mailbox admin credentials. Some IMAP servers let one administrator account open every mailbox. For Dovecot, which supports SASL, the UserName value is User_UserName*Admin_UserName (the asterisk is a configurable separator), and the password is the admin account's password. This avoids touching user passwords, but it needs a master account configured on the server. On shared hosting that is the host's decision, so ask them whether it is available.
  • Known user passwords. If users give you their passwords, nothing changes for them until cutover.
  • Reset passwords. Reset each mailbox password in the hosting control panel to a temporary value and record it in the CSV. Users can't reach their old mailbox with their own password afterwards unless you give them the new one.

If you use user passwords, stop users from changing them on the old server until the migration is finished. Microsoft notes that a password change before the mailbox is migrated makes the migration fail, and a change after the initial copy stops new mail from being synchronized.

Treat the CSV file as a secret: it contains working credentials. Delete it when the migration is finished.

Step 2: Create the IMAP migration endpoint

The endpoint stores the connection settings to the old server and controls how many mailboxes are migrated at once.

In the Exchange admin center

  1. Open the Exchange admin center and go to Migration.
  2. Select Endpoints, then Add.
  3. Choose IMAP as the migration type.
  4. Enter a Migration endpoint name and the IMAP server (for example, mail.contoso.com). The remaining defaults work for most servers.
  5. Select Create.

In PowerShell

Test the connection first, then create the endpoint with SSL on port 993:

Test-MigrationServerAvailability -IMAP -RemoteServer mail.contoso.com -Port 993 -Security Ssl
 
New-MigrationEndpoint -IMAP -Name cPanelEndpoint -RemoteServer mail.contoso.com -Port 993 -Security Ssl
 
Get-MigrationEndpoint cPanelEndpoint | Format-List EndpointType,RemoteServer,Port,Security,Max*

Microsoft's guidance is that port 143 is typically used for unencrypted or TLS connections and port 993 for SSL. If the host limits connections, reduce parallelism on the endpoint, for example -MaxConcurrentMigrations 10 -MaxConcurrentIncrementalSyncs 5. Run a small test batch and adjust from there.

Step 3: Create and start the migration batch

In the Exchange admin center

  1. In Migration, select Add migration batch.
  2. Enter a batch name without spaces or special characters and choose Migrate to Exchange Online, then Next.
  3. Select IMAP migration and continue through Prerequisites for IMAP migration.
  4. On Set a migration endpoint, select the endpoint you created.
  5. On Add user mailboxes, select Import CSV file and upload your file.
  6. On Select configuration settings, use Migration filtering options to exclude folders such as trash and junk.
  7. On Schedule batch migration, choose who receives reports and how the batch starts, then Save and Done.

In PowerShell

$csv = [System.IO.File]::ReadAllBytes("C:\Migration\cpanel-batch1.csv")
 
New-MigrationBatch -Name cPanelBatch1 `
  -SourceEndpoint cPanelEndpoint `
  -CSVData $csv `
  -ExcludeFolders "Trash","Junk" `
  -NotificationEmails admin@contoso.com `
  -AutoStart

ExcludeFolders takes folder names relative to the IMAP root on the source server, isn't case-sensitive and doesn't accept wildcards. Folder names differ between hosts, so check the exact names in a mail client connected to the old server before you exclude anything. Without -AutoStart, start the batch later with Start-MigrationBatch -Identity cPanelBatch1.

Step 4: Monitor and verify

Check the batch and each user:

Get-MigrationBatch -Identity cPanelBatch1 | Format-List Status
 
Get-MigrationUser -BatchId cPanelBatch1 | Get-MigrationUserStatistics
 
Get-MigrationUserStatistics -Identity alex@contoso.com -IncludeReport | Format-List Status,Error,Report
 
Get-MigrationUserStatistics -Identity alex@contoso.com | Format-List SkippedItemCount,SkippedItems

In the Exchange admin center, select the batch under Migration and use View details in the details pane to open the per-user status report.

After the initial copy, the migration endpoint keeps mailboxes in sync through incremental synchronization, which runs once every 24 hours. That is why the batch stays active through the cutover rather than finishing on its own.

Ask a few users to sign in to Outlook on the web, check that their folders and recent mail are present, set their time zone, and send a test message to another Microsoft 365 user.

Step 5: Cut over mail flow

Switch the MX record

  1. In the Microsoft 365 admin center, go to Settings > Domains, select the domain, then DNS records > Manage DNS, and keep Exchange and Exchange Online Protection selected.
  2. Copy the MX value shown on the Add DNS records page. Don't type it from memory; Microsoft 365 generates it for your domain.
  3. At your DNS host, add the Microsoft 365 MX record with the highest priority available (typically 0), and either remove the old MX records or give them a lower priority (a higher number).
  4. Add the autodiscover CNAME shown in the same page so Outlook can configure itself.
  5. Update SPF. If the domain already has an SPF record, don't add a second one; add include:spf.protection.outlook.com to the existing record so there is a single SPF TXT record. If nothing else sends mail for the domain any more, the record becomes v=spf1 include:spf.protection.outlook.com -all.

Fix cPanel email routing

This step is easy to miss when DNS is hosted somewhere other than the cPanel server. In cPanel, go to Email > Email Routing. Its Automatically Detect Configuration setting reads only the local zone file on the hosting server and does not perform a DNS lookup. If that zone still lists the server itself as the mail exchanger, cPanel keeps treating the domain as local, and any mail generated on the server, such as website contact forms, is delivered to the old local mailboxes instead of Exchange Online.

After the cutover, select Remote Mail Exchanger for the domain and select Change. With that setting, the server no longer accepts mail for the domain and sends all mail for it to the lowest-numbered mail exchanger, which is now Microsoft 365. If your host lets you edit the zone in Zone Editor, update the MX record there as well so automatic detection gives the right answer.

Wait, then remove the batch

It can take up to 72 hours for other mail systems to pick up the new MX record. Leave the batch running for at least 72 hours so that any mail that still arrives at the old server is copied across by the daily synchronization. Before you delete the batch, confirm that:

  • All users are working in Exchange Online.
  • The batch's last synced time is later than the moment mail started arriving directly in Microsoft 365.

Then remove the batch:

Remove-MigrationBatch -Identity cPanelBatch1
Get-MigrationBatch cPanelBatch1

The second command returns the batch with status Removing, or an error saying it can't be found. Once the batch is gone, mail delivered to the old server is no longer copied, so keep the hosting mailboxes until you are certain nothing still points at them, then close them.

Troubleshooting

Test-MigrationServerAvailability fails or the batch can't connect. Confirm the server name, port and security setting against the host's mail client settings. A firewall in front of the IMAP server might need to allow traffic from Microsoft datacenters; Microsoft publishes those addresses in its Exchange Online URLs and IP address ranges list, which you can pass to your host.

A user fails with an authentication error. The password in the CSV is wrong or was changed after you built the file. Fix the CSV entry (or reset the password again) and retry that user.

Users report missing folders. Look for folders with a forward slash in the name, folders you excluded, and folder names that differ from what you expected. Rename and let the next incremental synchronization pick them up.

Some messages didn't arrive. Check SkippedItemCount and SkippedItems. Messages over 35 MB and anything beyond the 500,000-item limit aren't migrated.

The migration is slow or stalls. The usual cause is connection limits on the source. Lower MaxConcurrentMigrations on the endpoint, run batches out of hours, and migrate the largest mailboxes in their own batch.

After cutover, website form mail still lands in the old mailboxes. cPanel email routing is still set to local. Change it to Remote Mail Exchanger as described above.

Mail to some users bounces after cutover. The user doesn't have a licensed Exchange Online mailbox with that address. Add the address to the right mailbox in Microsoft 365.

Don't delete or readdress mailboxes mid-migration. Microsoft warns that changing the SMTP address of, or deleting, a migrated mailbox before the batch is removed causes migration errors.

Checklist

  • Domain verified and users created and licensed in Microsoft 365.
  • MRM and archive policies off for target mailboxes during the migration.
  • IMAP server name and port confirmed; connection limits raised where possible.
  • MX TTL lowered to 3,600 seconds or less before starting.
  • CSV built with EmailAddress, UserName and Password; stored securely and deleted afterwards.
  • Test batch with a few mailboxes, then production batches.
  • Users checked their mail in Outlook on the web; contacts and calendars exported separately.
  • MX, autodiscover and SPF updated from the values in the Microsoft 365 admin center.
  • cPanel email routing set to Remote Mail Exchanger.
  • Batch left running at least 72 hours after cutover, then removed.

References

Questions people ask

Does an IMAP migration move contacts and calendars?

No. IMAP migration to Exchange Online only moves items in the inbox and other mail folders. Contacts, calendar items and tasks are not migrated, so users need to export and import them separately or recreate them.

What are the limits of an IMAP migration to Microsoft 365?

Microsoft documents a maximum of 500,000 items per mailbox, migrated from newest to oldest, and a maximum message size of 35 MB. A single migration CSV file can list up to 50,000 mailboxes and be up to 10 MB. Folders with a forward slash in their name are not migrated.

When can I delete the IMAP migration batch?

After you switch the MX record, wait at least 72 hours, confirm that all users are working in Exchange Online, and check that the batch has synchronized at least once after mail started arriving directly in Microsoft 365. Deleting the batch stops synchronization, so mail that still lands on the old server afterwards is not copied across.

Do I need every user's cPanel password?

You need credentials that can open each mailbox over IMAP. Either use each user's password, reset passwords to temporary ones you record in the CSV file, or, on servers that support it, use a mailbox admin account in the format the IMAP server expects, such as the Dovecot format user*admin.

Exchange OnlineIMAPcPanelMigration batchesPowerShell
  1. Exchange Online mail flow rules: disclaimers, external tags and blocking

    Build Exchange Online mail flow rules for outbound disclaimers, external sender warnings and attachment blocking, then test, order and troubleshoot them in the EAC and PowerShell.

    Microsoft 36514 min read
  2. Exchange Online migration batch stuck on Syncing: causes and fixes

    Find out why an Exchange Online migration batch sits on Syncing, read the per-user stall reasons in PowerShell, and apply the right fix for concurrency, throttling, source health or skipped items.

    Microsoft 36513 min read
  3. Migrating public folders to Exchange Online with batch migration

    Move modern public folders from Exchange Server 2016, 2019 or Subscription Edition to Exchange Online with the native batch migration: scripts, mapping CSV, lock-down, completion and verification.

    Microsoft 36512 min read