Migrate

Migrate Gmail to On-Prem Exchange: A Regulated-Industry Playbook

Move from Gmail or Google Workspace into on-prem Exchange via IMAP. Real auth quirks, retention, journaling, and cutover steps.

PS

Priya Shah

Senior Systems Engineer

· 10 min read
Documents representing a Gmail to Exchange migration in a regulated environment

This direction is rare but real. The usual scenario: an acquisition where the parent company runs on-prem Exchange and has compliance reasons (data residency, journaling, an existing legal-hold infrastructure) it cannot extend to Google Workspace. Or a regulated industry where the auditor has flagged Workspace as outside acceptable controls and the path of least resistance is back to a self-hosted Exchange estate. Either way, you need to move five years of Gmail mail into Exchange without losing thread structure, attachments, or audit trail. Here is the playbook.

Gmail
Exchange

Skip the manual setup — let Mailbox Taxi handle it

One desktop app, every IMAP provider, zero data leaving your machine.

When this direction makes sense

Most email migrations move from on-prem to cloud. The reverse direction happens for specific reasons:

  • Data residency requirements that Workspace cannot meet for your specific jurisdiction (some Workspace regions still proxy through US infrastructure for certain operations).
  • Journaling and legal hold infrastructure built around Exchange and an on-prem archive (Veritas Enterprise Vault, Mimecast on-prem, Smarsh) that cannot be replicated in Workspace within the audit timeline.
  • Air-gapped environments (defence, intelligence, certain financial back-offices) where cloud mail is prohibited.
  • Acquisition rationalisation: parent company runs Exchange; the acquired entity ran Workspace; CFO mandates consolidation.

The work is mechanically straightforward — IMAP at Gmail's end, IMAP-import at Exchange's end — but the operational details (Gmail's namespace quirks, label-to-folder expansion, app passwords, MX cutover) need careful handling.

Pre-migration audit

On the Gmail side, you can pull a per-mailbox audit via the Workspace Admin Console reports, or per-user via the Gmail web UI under Settings → Storage.

For programmatic collection at scale, use the Workspace Admin SDK Reports API:

# pseudocode
from googleapiclient.discovery import build
service = build('reports', 'v1', credentials=creds)
results = service.userUsageReport().get(
    userKey='all',
    date='2026-05-20',
    parameters='gmail:num_emails_received_size_inboundtotalmbytes,'
               'accounts:used_quota_in_mb'
).execute()

Capture per mailbox:

  • Total size in GB
  • Total item count (approximate; Gmail counts conversations, not messages)
  • Label count and the top 10 labels by size
  • Whether 2FA is enabled (it should be, on Workspace especially)

Heads up

Gmail's label model is many-to-many. A message with three labels counts once in Gmail's storage but creates three folder copies in Exchange. Budget 10 to 20 percent storage inflation on the destination, especially for users with heavy label tagging.

For an exhaustive map of Gmail's IMAP behaviour, see our Gmail to Office 365 walkthrough — the source-side mechanics are identical, only the destination differs.

Exchange preparation

Provision Exchange:

  1. Mailbox database capacity: budget total Gmail size × 1.2 to account for label expansion, then add 30 percent headroom for normal mailbox growth.
  2. Create user mailboxes matching source Gmail addresses exactly. The migration batch maps source-to-destination by primary SMTP.
Import-Csv users.csv | ForEach-Object {
  New-Mailbox -Name $_.DisplayName -UserPrincipalName $_.Email `
    -Password (ConvertTo-SecureString $_.Password -AsPlainText -Force) `
    -OrganizationalUnit "OU=Users,DC=corp,DC=example,DC=com" `
    -Database "MBX-DB01"
}
  1. Enable IMAP is not required on Exchange's side for IMAP-import; Exchange uses its own EWS internally. The IMAP-source label on the migration batch refers to the source-side protocol.
  2. Throttling policy for the migration: create a relaxed policy and assign to the migration admin account.
New-ThrottlingPolicy -Name GmailMigration -EwsMaxConcurrency Unlimited `
  -EwsMaxSubscriptions Unlimited -EwsCutoffBalance Unlimited
Set-Mailbox migration-admin@corp.example.com -ThrottlingPolicy GmailMigration
  1. Migration endpoint configuration:
$creds = Get-Credential  # not used for IMAP per-user, but required by cmdlet
New-MigrationEndpoint -IMAP -Name "Gmail-IMAP" `
  -RemoteServer imap.gmail.com -Port 993 -Security Ssl `
  -Authentication Basic -SkipVerification:$false

Generating Gmail credentials

This is the most operationally heavy step. You need one of:

Per-user app passwords (most reliable for personal Gmail and Workspace alike). For each Gmail account, sign in, go to Account → Security → 2-Step Verification → App passwords, generate a 16-character password named "Exchange Migration". Store in your secrets manager.

OAuth via Workspace admin consent (only for Workspace sources). Configure a service account in Google Cloud Console, grant domain-wide delegation, and have Exchange's migration tool use that. Setup is complex; Exchange's native New-MigrationBatch does not natively support Google OAuth, so you typically need a third-party tool for this path.

For 95 percent of cases on the Exchange side, you collect app passwords. For 50 to 200 users, this is a half-day of admin work or a self-service flow with clear instructions.

Tip

If your security policy bans collecting user passwords (even app-specific ones), the alternative is a desktop migration tool where each user runs the migration themselves against their own account, with their own credentials, on their own machine. Mailbox Taxi supports this pattern.

Running the migration batch

Build the CSV of source-to-destination mappings:

EmailAddress,UserName,Password
alice@corp.example.com,alice@yourdomain.com,xxxx-xxxx-xxxx-xxxx
bob@corp.example.com,bob@yourdomain.com,yyyy-yyyy-yyyy-yyyy

Where EmailAddress is the destination, UserName is the source Gmail address, and Password is the source app password.

Start the migration:

New-MigrationBatch -Name "Gmail-Wave-1" `
  -SourceEndpoint "Gmail-IMAP" `
  -CSVData ([System.IO.File]::ReadAllBytes("C:\migration\wave1.csv")) `
  -TargetDeliveryDomain yourdomain.com `
  -ExcludeFolders "Spam,Bin,Trash,[Gmail]/Spam,[Gmail]/Trash" `
  -BadItemLimit 50

Start-MigrationBatch -Identity "Gmail-Wave-1"

Monitor progress:

Get-MigrationUserStatistics -BatchId "Gmail-Wave-1" |
  Select-Object Identity, Status, ItemsSynced, ItemsSkipped, BytesTransferred
  1. Pilot with three users

    Small, medium, large mailbox profiles. Run end-to-end, validate item counts, threading, and attachment integrity.

  2. Validate the pilot in Outlook

    Open each pilot mailbox in Outlook. Check folder hierarchy against source labels, confirm read/unread states, spot-check messages with attachments, verify the [Gmail]/Sent Mail label landed in Sent Items.

  3. Scale in waves of 20 to 50

    Larger batches risk Gmail's per-IP and per-account IMAP throttling. 20 to 50 is the safe range for most networks.

  4. Run delta syncs

    24 hours before MX cutover, complete a delta sync. Final delta runs 1 hour after MX change.

  5. Cut MX

    Switch MX from Google to your Exchange edge transport at the cutover moment. Verify with dig.

Gmail's [Gmail] namespace

Gmail exposes a special folder hierarchy:

  • [Gmail]/All Mail — every message regardless of label (Gmail's archive)
  • [Gmail]/Sent Mail — sent items
  • [Gmail]/Drafts — drafts
  • [Gmail]/Trash — trash
  • [Gmail]/Spam — spam
  • [Gmail]/Starred — starred items
  • [Gmail]/Important — Gmail's importance markers

Configure your migration batch to:

  • Exclude [Gmail]/All Mail — including it would double-copy every message (once via its label, once via All Mail).
  • Map [Gmail]/Sent Mail to Exchange's Sent Items.
  • Exclude [Gmail]/Trash and [Gmail]/Spam.
  • Map [Gmail]/Drafts to Drafts.

Exchange's New-MigrationBatch handles the All Mail exclusion automatically when the source is detected as Gmail. Confirm in the batch report that [Gmail]/All Mail shows zero items processed; if it shows positive numbers, your exclusion is not active.

Calendars and contacts

These do not move via IMAP migration. Per user:

Calendar: from Google Calendar, Settings → Import & export → Export. Download the ICS. Import via Outlook's File → Open & Export → Import/Export → Import an iCalendar (.ics).

Contacts: from Google Contacts, Export → Outlook CSV format. Import via Outlook's File → Open & Export → Import/Export → Import from another program or file → Comma Separated Values.

For 50 to 200 users, this is two to three days of admin work. Script the Google-side export with the Calendar API and Contacts API; the Outlook-side import via PowerShell's Import-Contact and ICS open via COM automation.

MX and DNS cutover

Publish the destination MX records (do not switch yet):

  • MX: your Exchange edge transport hostname, e.g., mail.corp.example.com priority 10.
  • SPF: include your Exchange edge IP block, e.g., v=spf1 ip4:203.0.113.0/24 -all.
  • DKIM: configure DKIM signing on Exchange (Exchange 2016 CU17+ supports native DKIM; earlier versions need a third-party signer like DKIM Signer for Exchange).
  • DMARC: start at p=none, tighten to p=quarantine after 30 days.

Cutover sequence:

T-7 days: user comms.

T-48 hours: drop MX TTL to 300 seconds.

T-24 hours: delta migration pass.

T-2 hours: notify users of upcoming downtime.

T-0: change MX from Google to your Exchange edge. Verify with dig MX corp.example.com @8.8.8.8 @1.1.1.1.

T+30 minutes: external test send/receive.

T+1 hour: final delta migration.

T+24 hours: verify SPF/DKIM/DMARC alignment.

Outlook configuration

Push new Outlook profiles via Group Policy or Intune:

  • Profile points at Exchange Autodiscover for the destination domain.
  • For users coming from Workspace, this is their first Outlook setup — budget help-desk time for the first 48 hours.
  • Calendar and contacts work natively in Outlook against Exchange (no plugin needed, unlike Workspace destinations).

For users who relied on Gmail-specific features (priority inbox, snooze, scheduled send), document the Outlook equivalents (focused inbox, follow-up flags, delayed delivery). Some have no equivalent.

Where Mailbox Taxi fits

Exchange's New-MigrationBatch handles bulk IMAP migrations competently when you have app passwords for everyone. It is less helpful in three scenarios:

  • Air-gapped environments where the migration host cannot reach imap.gmail.com directly but a workstation can (via proxy). Run the desktop tool on the workstation.
  • Filtered migrations: New-MigrationBatch does not support folder-level filtering beyond simple exclusions. Mailbox Taxi supports per-label and date-range filtering.
  • Per-user self-service: rather than collecting 500 app passwords, have each user run a desktop migration on their own machine with their own credentials.

It runs locally on Windows, Mac, or Linux, speaks Gmail-aware IMAP (handles [Gmail]/ namespace and label-to-folder mapping correctly), and writes to Exchange via IMAP or EWS.

For the broader source-side reference, the Google Workspace migration guide is the right pillar. For the destination side, the Exchange migration guide covers Exchange-target patterns generally. And for teams reconsidering whether on-prem Exchange is really the right destination, the Gmail to Office 365 walkthrough covers the more common cloud-to-cloud path. The Gmail to Outlook desktop guide covers the client-only case when you are not changing servers.

Common errors and fixes

AUTHENTICATIONFAILED — wrong app password, or 2FA was disabled on the source account (in which case Gmail blocks IMAP entirely until re-enabled). Re-generate the app password.

[ALERT] Web login required — Gmail flagged the IMAP session as suspicious. The user must sign in to Gmail via web from a machine on the same network. The flag clears within 30 minutes.

Too many simultaneous connections — Gmail caps at 15 concurrent IMAP sessions per account. Reduce migration concurrency.

Folder UTF-7 conversion error — non-ASCII label names. Rename via Gmail web UI before migrating.

Message too large for destination — Exchange has a default 25 MB message-size limit set by MaxReceiveSize on the connector. Raise it for the migration window:

Set-ReceiveConnector "MBX01\Default MBX01" -MaxMessageSize 100MB

The complete email migration guide has a broader error catalogue.

Post-cutover validation

In the first week:

  1. Item count delta: compare source label totals to destination folder totals. Variance under 5 percent is normal (label expansion accounts for the bulk).
  2. DNS hygiene: confirm SPF/DKIM/DMARC via MXToolbox; watch DMARC reports for the first 30 days.
  3. Journaling and legal hold: confirm new mail is journaling correctly and any legal-hold tags from Workspace have been recreated as Exchange retention tags.

After 30 days of stable Exchange operation, decommission Google Workspace. Export any remaining Vault data first if you have eDiscovery obligations. Cancel licences at the end of the billing cycle to avoid prorated charges.

Try Mailbox Taxi

Migrate your mailbox the easy way

Join the waitlist for early access and lock in launch pricing.

Related reading

Try Mailbox Taxi

Migrate your mailbox the easy way

Join the waitlist for early access and lock in launch pricing.