Overview
Moving from Google Workspace to Microsoft 365 involves more than copying mailboxes. You need identities in Microsoft Entra ID, mail routing that works while some users are on Gmail and others are on Exchange Online, a Google Cloud service account with the right delegated permissions, and a clean DNS cutover at the end.
Microsoft provides two native tools for this:
- Google Workspace migration in Exchange Online (Exchange admin center or Exchange Online PowerShell) for mail, calendar, contacts and Gmail filters.
- Migration Manager for Google Drive content (My Drive and shared drives) into OneDrive and SharePoint.
This guide walks through a staged migration, where users move in batches and the MX record is switched once all batches are complete. The examples use contoso.com as the primary domain, o365.contoso.com as the routing subdomain that points to Microsoft 365, and gsuite.contoso.com as the routing subdomain that points to Google.
Note that Google Workspace migration is not available for Office 365 US Government GCC High or DoD tenants.
Phase 1: Planning and Inventory
Start with an inventory of what exists in Google Workspace and decide what moves, what is recreated and what is left behind.
| Item | Native migration path | Notes |
|---|---|---|
| Gmail messages | Exchange Online Google Workspace migration | Default maximum message size is 35 MB unless you raise transport limits |
| Gmail filters | Migrated as Outlook rules (disabled) | Use -SkipRules to skip |
| Calendar events | Exchange Online Google Workspace migration | Shared calendars, event colors and room bookings are not migrated |
| Contacts | Exchange Online Google Workspace migration | Maximum of three email addresses per contact; Gmail tags and contact URLs not migrated |
| Vacation / auto-reply settings | Not migrated | Users reconfigure in Outlook |
| My Drive and shared drives | Migration Manager | Docs, Sheets, Slides converted to Office formats |
| Google Groups | Not migrated | Recreate as distribution groups or Microsoft 365 Groups |
| Google Chat, Sites, Keep, Maps | Not migrated | Export, archive, or use a third-party tool |
Collect for every user: primary address, aliases, mailbox size, Drive size, shared drive memberships, delegation and send-as arrangements, and which mobile devices they use. Group users into batches by department or team so that people who share calendars and documents heavily move together.
Two pre-migration hygiene items from Microsoft's guidance are worth doing early:
- Disable MRM and archive policies for the users being migrated until their migration completes. The migration service is not aware of retention policies, so items deleted or archived by a policy during migration are flagged as "missing", which makes genuine data loss hard to spot.
- Plan for large items. Messages larger than the transport limit (35 MB by default) are not migrated unless you raise the limit.
Phase 2: Licensing
Every user needs a Microsoft 365 license that includes Exchange Online (and OneDrive and SharePoint for the Drive migration). The timing of the Exchange license matters:
- Users must exist in Exchange Online as mail users before their batch starts, not as licensed mailboxes.
- When a batch starts, the migration service converts the mail users into mailboxes. Assign the Exchange Online license after this point. Microsoft gives you 30 days to assign it.
If users need Teams or OneDrive before their mailbox moves, assign the license with the Exchange Online service plan disabled and enable that plan after the batch has started. Assigning a license that includes Exchange Online before the batch starts provisions a mailbox, which defeats the mail-user design the migration relies on.
Phase 3: Identity and User Provisioning
Cloud-only provisioning
For organizations without Active Directory, create a mail user for each Google Workspace user. Each mail user needs:
- A primary SMTP address on the primary domain (
will@contoso.com), matching the Google Workspace primary address. - An
ExternalEmailAddresspointing to the user's address on the Google routing subdomain (will@gsuite.contoso.com). - A proxy address on the Microsoft 365 routing subdomain (
will@o365.contoso.com).
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
$users = Import-Csv "C:\Migration\users.csv" # columns: FirstName,LastName,Alias
foreach ($u in $users) {
$upn = "$($u.Alias)@contoso.com"
New-MailUser -Name "$($u.FirstName) $($u.LastName)" `
-FirstName $u.FirstName -LastName $u.LastName `
-MicrosoftOnlineServicesID $upn `
-PrimarySmtpAddress $upn `
-ExternalEmailAddress "$($u.Alias)@gsuite.contoso.com" `
-Password (Read-Host "Initial password for $upn" -AsSecureString)
Set-MailUser -Identity $upn -EmailAddresses @{add = "smtp:$($u.Alias)@o365.contoso.com"}
}In practice you would generate initial passwords or use a temporary access method rather than prompting for each user; the prompt keeps the sample short.
Organizations with Active Directory
If you have on-premises Active Directory, Microsoft Entra Connect can provision the users instead. Microsoft's prerequisites note two complications: the users still need to be mail-enabled (which requires on-premises Exchange management tooling to manage the attributes properly), and directory synchronization may need to be adjusted so that the migration process can convert the synchronized mail users into mailboxes. Read that section of the prerequisites carefully and prove the flow with a pilot batch before committing to it.
Whichever route you choose, also create recipients for addresses that are not users: Google Groups, shared aliases and service accounts. Because contoso.com will be an authoritative accepted domain in Exchange Online, mail sent by already-migrated users to an address that has no recipient in Exchange Online is rejected. Either create matching recipients that route back to the Google routing subdomain, or set the accepted domain to Internal Relay with an outbound connector to Google for the coexistence period.
Phase 4: Routing Subdomains for Coexistence
Microsoft requires two routing subdomains before the migration starts. Both are added in the Google Admin console as User alias domains; using subdomains of your primary domain lets Google verify them automatically.
| Subdomain | Added in Google as | DNS MX points to | Also required |
|---|---|---|---|
o365.contoso.com | User alias domain | Microsoft 365 | Must be added and verified as an accepted domain in Microsoft 365. Used as the TargetDeliveryDomain of each batch |
gsuite.contoso.com | User alias domain | Google Workspace | Must not be an accepted domain in Microsoft 365 |
Notes:
- Do not use
contoso.onmicrosoft.comas the Microsoft 365 routing domain. Microsoft documents that this occasionally causes problems it cannot help with, because Google then sends verification emails for each forwarding address. - Google can take up to 24 hours to propagate the alias domain to all users.
- If your Exchange Online organization uses non-default transport settings, make sure mail can be automatically forwarded to
gsuite.contoso.com: either the default remote domain (*) allows automatic forwarding, or create a remote domain forgsuite.contoso.comthat does. Also check your outbound anti-spam policy, because external automatic forwarding is blocked by default and the migration relies on mailbox forwarding to the Google routing domain during coexistence. - The migration also needs to set forwarding on the Google side. If users are not allowed to set an automatic forwarding address in Gmail, the tool cannot set it either, so enable automatic forwarding in the Google Admin console for the users being migrated.
Phase 5: Google Cloud Project, Service Account and Delegation
The Exchange Online migration service authenticates to Google with a service account that has domain-wide delegation. You can let the Exchange admin center automate this (the Automate the configuration of your Google Workspace for migration option creates the project, service account, key and API enablement after you sign in to Google), or configure it manually.
The Google administrator needs permission to create projects and service accounts (the Project Creator role and the Create Service Accounts role). Manual configuration looks like this:
- In the Google Cloud console, create a project and a service account in it.
- Note the service account's Unique ID (the client ID); you need it for delegation.
- Enable domain-wide delegation for the service account.
- Create a JSON key for the service account and store it securely. Anyone holding this key can read every mailbox in scope.
- In the API Library for the project, enable the Gmail API, Google Calendar API, Contacts API and People API.
- In the Google Admin console, go to Security > API Controls > Manage Domain Wide Delegation, select Add new, enter the client ID, and add the scopes Microsoft documents, comma-separated with no spaces:
https://mail.google.com/,https://www.googleapis.com/auth/calendar,https://www.google.com/m8/feeds/,https://www.googleapis.com/auth/gmail.settings.sharing,https://www.googleapis.com/auth/contactsIf the scopes are entered incorrectly, the endpoint test may pass but the batch fails later, so compare the authorized list against the documentation. Delegation changes can take anywhere from 15 minutes to 24 hours to propagate.
Phase 6: Migration Endpoint and Batches
Create the migration endpoint
Test connectivity with the JSON key and a Google Workspace super admin address, then create the endpoint:
$key = [System.IO.File]::ReadAllBytes("C:\Migration\gws-migration-key.json")
Test-MigrationServerAvailability -Gmail -ServiceAccountKeyFileData $key -EmailAddress admin@contoso.com
New-MigrationEndpoint -Gmail -Name gmailEndpoint `
-ServiceAccountKeyFileData $key `
-EmailAddress admin@contoso.com `
-MaxConcurrentMigrations 20 `
-MaxConcurrentIncrementalSyncs 10The concurrency values shown are the Exchange admin center defaults. The administrator running these cmdlets needs at least the Recipient Management role group in Exchange Online.
Build the batch CSV
The CSV supports two columns: EmailAddress (required, the user's primary address in Microsoft 365) and Username (optional, the Gmail address when it differs).
EmailAddress
will@contoso.com
user123@contoso.comCreate, start and monitor the batch
New-MigrationBatch -Name Batch01-Finance -SourceEndpoint gmailEndpoint `
-CSVData ([System.IO.File]::ReadAllBytes("C:\Migration\Batch01-Finance.csv")) `
-TargetDeliveryDomain "o365.contoso.com" `
-NotificationEmails migration-team@contoso.com
Start-MigrationBatch -Identity Batch01-Finance
# Monitor progress
Get-MigrationBatch -Identity Batch01-Finance | Format-List Status,TotalCount,SyncedCount,FailedCount
Get-MigrationUser -BatchId Batch01-Finance | Format-Table Identity,Status
Get-MigrationUserStatistics -Identity will@contoso.com -IncludeReport | Format-ListOptional parameters on New-MigrationBatch worth knowing:
-ExcludeFolderleaves out named folders or Gmail labels, which reduces the data moved and the size of the new mailbox.-SkipRulesskips migration of Gmail filters.
When the batch starts, the mail users are converted to mailboxes and their ExternalEmailAddress becomes a forwarding address to the Google routing subdomain, so new mail keeps landing in Gmail while the initial sync runs. Assign Exchange Online licenses now.
Complete the batch
When the batch reaches Synced, complete it:
Complete-MigrationBatch -Identity Batch01-FinanceCompletion runs a final incremental sync, removes the forwarding from Microsoft 365 to Google, and adds forwarding in Gmail from the user's Google mailbox to the Microsoft 365 routing subdomain. From this point the migrated users work in Outlook, and mail that still arrives at Google (because MX has not moved yet) is forwarded to Exchange Online.
Throttling and batch sizing
- On the Microsoft side, the endpoint's concurrency settings limit how many mailboxes sync at once; batches larger than that simply queue.
- On the Google side, Gmail, Calendar and Contacts API quotas apply to the service account and per user. Microsoft notes that calendar and contact throughput depends entirely on the quota available to your service account.
- Start with a pilot of IT staff and a few volunteers, measure how long a typical mailbox takes, then size production batches so that each one can sync, be validated and be completed within its planned window.
- Schedule completion so users in the same team switch to Outlook on the same day.
Phase 7: Google Drive to OneDrive and SharePoint with Migration Manager
Open Setup > Migration resources in the Microsoft 365 admin center and choose Google Workspace to start a Migration Manager project. You need a OneDrive/SharePoint admin, the Microsoft 365 Migration Administrator role, or Global Administrator in Microsoft 365, and a Google Workspace admin who can install and authorize the Microsoft 365 migration app. For tenants with fewer than 300 licenses, Migration Manager may start in its simplified Lite experience.
The standard workflow has six steps:
- Connect to Google: sign in and install the Microsoft 365 migration app from the Google Workspace Marketplace.
- Scan and assess: add drives for scanning and review the scan reports.
- Copy to the migrations list once a drive is marked ready.
- Review destination paths: My Drive normally maps to the user's OneDrive; shared drives map to SharePoint or Teams sites.
- Map identities: map Google users, groups and domains to their Microsoft 365 counterparts.
- Migrate and monitor.
Behaviors to plan around:
- Google Docs, Sheets and Slides are converted to
.docx,.xlsxand.pptx. Google Drawings arrive as PNG files. Google Forms are migrated if you designate a Forms destination. - Google Sites and Google Maps are not migrated. Shortcuts are skipped, and orphaned (unorganized) files are not scanned or migrated.
- File-level permission migration is off by default; without it, files inherit the permissions of the destination folder. Identity mapping alone does not carry permissions across.
- For shared drives, create a Microsoft 365 group with the same membership as the Google group first and map one to the other.
- External sharing links are not recreated, and content is not shared with external collaborators automatically.
- Only the latest version is copied unless you configure file version settings.
- Running Migrate again performs a delta pass that copies new and changed files. Avoid reorganizing folders between passes, because renamed paths are copied again as new content.
- Make sure each user's OneDrive is provisioned before migrating into it (for example with
Request-SPOPersonalSite -UserEmailsfor users who have not signed in yet).
Phase 8: DNS Cutover
When every batch is complete, switch the primary domain's mail flow to Microsoft 365. Lower the TTL on the MX record a day or two beforehand.
| Record | Value |
|---|---|
MX (contoso.com) | The Exchange Online Protection host shown in the Microsoft 365 admin center for your domain. Copy it exactly rather than constructing it |
CNAME autodiscover | autodiscover.outlook.com |
| TXT (SPF) | During transition: v=spf1 include:spf.protection.outlook.com include:_spf.google.com ~all. Remove the Google include once Google no longer sends mail for the domain |
| DKIM | Two CNAMEs published from the values Exchange Online provides, then signing enabled |
| DMARC | Keep your existing record; review aggregate reports to confirm Exchange Online mail passes SPF or DKIM alignment before tightening the policy |
Enable DKIM signing for the domain once the CNAMEs are published:
# Create the signing configuration if it does not exist yet
New-DkimSigningConfig -DomainName contoso.com -Enabled $false
# Read the CNAME targets to publish in DNS
Get-DkimSigningConfig -Identity contoso.com | Format-List Selector1CNAME,Selector2CNAME
# After the CNAMEs resolve, turn signing on
Set-DkimSigningConfig -Identity contoso.com -Enabled $trueAfter the MX change propagates, mail for contoso.com arrives directly in Exchange Online. Keep the Google tenant and the forwarding in place for a while to catch mail from senders with cached MX records.
Phase 9: Post-Cutover Checklist
- Confirm inbound mail from several external providers lands in Exchange Online, and outbound mail passes SPF, DKIM and DMARC at the receiver (check message headers).
- Ask users to review and enable their migrated inbox rules and to set up auto-replies and signatures again.
- Recreate shared calendars, room mailboxes and resource booking policies; room bookings are not migrated.
- Reconfigure mobile devices with the Outlook app or native Exchange ActiveSync profiles, and remove Google accounts from devices on a scheduled date.
- Verify Drive migration reports, then re-share any content that relied on external sharing links.
- Re-enable MRM and archive policies that you disabled before migration.
- Remove the routing subdomains, the extra aliases and, if used, the Internal Relay configuration and outbound connector to Google.
- Revoke the Google service account key and delete the delegation entry once all migrations are finished.
- Decommission the Google Workspace subscription only after a final check that nothing still routes there.
Common Errors and How to Fix Them
| Symptom | Likely cause | Fix |
|---|---|---|
Test-MigrationServerAvailability or the endpoint wizard fails to authenticate | Wrong JSON key, client ID not authorized, scopes mistyped, or delegation not yet propagated | Re-check the client ID and scope string; wait up to 24 hours after authorizing |
GmailForwardingAddressRequiresVerificationException during a batch | Google requires verification of the forwarding address | Follow Microsoft's note for this error in the prerequisites; using a subdomain of the primary domain for routing avoids most verification prompts |
| Batch cannot complete | Microsoft 365 routing domain is not verified, or Google has not finished setting up the alias domain | Verify o365.contoso.com in Microsoft 365 and confirm it is Active in Google |
| Users report "missing" items in validation | MRM or archive policies moved or deleted items during sync | Disable those policies for users in flight, then re-run validation |
| Migrated users do not receive mail sent to their Gmail address | Gmail automatic forwarding is disallowed for those users | Allow automatic forwarding in the Google Admin console, then set or verify the forwarding for the affected users |
| Mail to un-migrated users stuck or bounced from Exchange Online | Automatic forwarding blocked by remote domain or outbound spam policy | Allow automatic forwarding to gsuite.contoso.com for users in active batches |
| User already has a mailbox and does not migrate cleanly | Exchange Online license assigned before the batch started | Provision as a mail user and assign the license only after the batch starts |
| Large attachments missing | Message exceeds the transport size limit | Raise the limit before migration or accept and document the exclusion |
References
- Perform a Google Workspace migration to Microsoft 365 or Office 365
- Google Workspace migration prerequisites in Exchange Online
- Perform an automated Google Workspace migration in the EAC
- Migrate mail from Google Workspace to Microsoft 365 (manual method)
- Perform Google Workspace migration using Exchange Online PowerShell
- Completion of migration batch in Exchange Online PowerShell
- Overview of the Google Workspace migration process
- Migrate Google Workspace to Microsoft 365 with Migration Manager
- Migration Manager Google FAQs
- Unsupported file types in Migration Manager