Exchange ServerHow-to

Migrating public folders to Exchange Online: the batch steps and the errors that stop them

Move public folders from Exchange Server SE or 2019 to Exchange Online with Microsoft's batch scripts: prerequisites, lock-down, cutover and the errors that stall the batch.

Public folders are usually the last thing left on-premises once the mailboxes have moved. Microsoft's batch migration copies them to Exchange Online with a handful of scripts and a single migration batch, but it's unforgiving about preparation. Here's the sequence for Exchange Server SE, 2019 and 2016, the commands at each step, and the errors that most often stop the batch.

Errors this guide fixes

  • Cannot find a recipient that has mailbox GUIDNew-MigrationBatch (Exchange Online)
  • Error: Dumpster of the Dumpster folder.Public folder migration request
  • Request was quarantined because of the following error: The given key wasn't present in the dictionary.Public folder migration request
  • No active public folder mailboxes were foundComplete-MigrationBatch
  • Couldn't find the public folder mailbox.Get-PublicFolder (after lock-down)
  • 5.7.13NDR (mail to migrated public folders)
  • 5.4.1NDR (mail to migrated public folders)
How this guide is organised: Prerequisites → Step-by-step → The errors that stop the batch → Verify → Tips and gotchasFlow diagram of the article's sections in reading order: 1. Prerequisites. 2. Step-by-step (9 steps: Download the scripts and validate the source; Prepare on-premises; Prepare Exchange Online; Generate the mapping files; Create the target mailboxes in Exchange Online; Sync mail-enabled folders, then create and start the batch; and 3 more). 3. The errors that stop the batch. 4. Verify. 5. Tips and gotchas. Toolbox: Export-ModernPublicFolderStatistics.ps1, Sync-ModernMailPublicFolders.ps1, Get-MoveRequest, SourceSideValidations.ps1, C:\PFScripts.1Prerequisites2Step-by-step3The errors thatstop the batch4Verify5Tips andgotchas1Downloadthe scripts…2Prepareon-premis…3PrepareExchange…4Generatethe mappi…5Create thetarget mai…6Syncmail-enabl…+3 moreTOOLBOXExport-ModernPublicFolderStatisti…Sync-ModernMailPublicFolders.ps1Get-MoveRequestSourceSideValidations.ps1C:\PFScriptsHow this guide is organised: Prerequisites → Step-by-step → The errors that stop the batch → Verify → Tips and gotchasFlow diagram of the article's sections in reading order: 1. Prerequisites. 2. Step-by-step (9 steps: Download the scripts and validate the source; Prepare on-premises; Prepare Exchange Online; Generate the mapping files; Create the target mailboxes in Exchange Online; Sync mail-enabled folders, then create and start the batch; and 3 more). 3. The errors that stop the batch. 4. Verify. 5. Tips and gotchas. Toolbox: Export-ModernPublicFolderStatistics.ps1, Sync-ModernMailPublicFolders.ps1, Get-MoveRequest, SourceSideValidations.ps1, C:\PFScripts.1Prerequisites2Step-by-step1Download the scripts and validate the source2Prepare on-premises3Prepare Exchange Online4Generate the mapping files5Create the target mailboxes in Exchange Online6Sync mail-enabled folders, then create and startthe batch+3 more3The errors that stop the batch4Verify5Tips and gotchasTOOLBOXExport-ModernPublicFolderStatistics.ps1Sync-ModernMailPublicFolders.ps1Get-MoveRequestSourceSideValidations.ps1C:\PFScripts
At a glance: how this guide is organised · 9 steps · 5 key settings and tools

Prerequisites#

  • Versions: Exchange 2016 CU4 or later, or any Exchange 2019 build; SE is covered by the same procedure. If you installed a CU without preparing Active Directory, run Setup.exe /PrepareAD first, or the migration parameters won't exist.
  • Permissions: Organization Management in Exchange Online; Organization Management or Server Management on-premises.
  • MRSProxy enabled on at least one server that hosts public folder mailboxes, reachable from Exchange Online. If endpoint creation fails, see fixing hybrid migration endpoint errors.
  • Users first: migrate the people who use the folders before the folders themselves.
  • Limits: at most 100 target public folder mailboxes during the migration, each up to 100 GB (Microsoft suggests filling them to about half). Shrink or split any single folder over 25 GB first.
  • One batch only, created in Exchange Online PowerShell; the EAC can't do it. Plan downtime: Microsoft recommends allowing at least 48 hours for the final sync.

Step-by-step#

1. Download the scripts and validate the source#

Put SourceSideValidations.ps1, Export-ModernPublicFolderStatistics.ps1, ModernPublicFolderToMailboxMapGenerator.ps1, Sync-ModernMailPublicFolders.ps1 and SetMailPublicFolderExternalAddress.ps1 in one folder, such as C:\PFScripts. Run .\SourceSideValidations.ps1 on a Mailbox server and fix everything it reports: orphaned or duplicate mail-enabled folder objects and bad permissions are what slow or break migrations later.

2. Prepare on-premises#

PowerShell
# Accepted domain that keeps mail to public folders flowing during the DNS transition
New-AcceptedDomain -Name PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99 `
  -DomainName contoso.mail.onmicrosoft.com -DomainType InternalRelay

# Folders with \ or / in the name may not reach their target mailbox: rename them
Get-PublicFolder -Recurse -ResultSize Unlimited |
  Where-Object { $_.Name -like "*\*" -or $_.Name -like "*/*" } | Format-List Name, Identity, EntryId

# Both values should be False unless a previous attempt is being discarded
Get-OrganizationConfig | Format-List PublicFolderMailboxesLockedForNewConnections, PublicFolderMailboxesMigrationComplete

# Snapshots to compare with afterwards
Get-PublicFolder -Recurse -ResultSize Unlimited | Export-CliXML OnPrem_PFStructure.xml
Get-PublicFolderStatistics -ResultSize Unlimited | Export-CliXML OnPrem_PFStatistics.xml
Get-MailPublicFolder -ResultSize Unlimited | Export-CliXML OnPrem_MEPF.xml

If Microsoft Entra Connect syncs your directory, clear Exchange Mail Public Folders under Configure › Customize synchronization options › Optional features.

3. Prepare Exchange Online#

Get-MigrationBatch | Where-Object { $_.MigrationType.ToString() -eq "PublicFolder" } and Get-Mailbox -PublicFolder should both return nothing. Remove old public folder batches; if public folders already exist in the cloud, find out who created them before deleting anything.

4. Generate the mapping files#

PowerShell
.\Export-ModernPublicFolderStatistics.ps1 stats.csv
.\ModernPublicFolderToMailboxMapGenerator.ps1 -MailboxSize 50GB -MailboxRecoverableItemSize 1GB `
  -ImportFile .\stats.csv -ExportFile map.csv

map.csv lists only folder trees and large folders with their target mailbox; children follow their parent. Rename the generic Mailbox1, Mailbox2 targets if they clash with existing names.

5. Create the target mailboxes in Exchange Online#

PowerShell
$mappings = Import-Csv C:\PFScripts\map.csv
$primary = ($mappings | Where-Object FolderPath -eq "\").TargetMailbox
New-Mailbox -HoldForMigration:$true -PublicFolder -IsExcludedFromServingHierarchy:$false $primary
($mappings | Where-Object TargetMailbox -ne $primary).TargetMailbox | Sort-Object -Unique |
  ForEach-Object { New-Mailbox -PublicFolder -IsExcludedFromServingHierarchy:$false $_ }

6. Sync mail-enabled folders, then create and start the batch#

On-premises, run .\Sync-ModernMailPublicFolders.ps1 -CsvSummaryFile:sync_summary.csv and note the hierarchy GUID from (Get-OrganizationConfig).RootPublicFolderMailbox.HierarchyMailboxGuid.GUID. It must come from on-premises, not Exchange Online. Then in Exchange Online PowerShell:

PowerShell
$cred  = Get-Credential CONTOSO\pfadmin
$bytes = [System.IO.File]::ReadAllBytes('C:\PFScripts\map.csv')
$ep = New-MigrationEndpoint -PublicFolder -Name PublicFolderEndpoint -RemoteServer mail.contoso.com -Credentials $cred
New-MigrationBatch -Name PublicFolderMigration -CSVData $bytes -SourceEndpoint $ep.Identity `
  -SourcePfPrimaryMailboxGuid <GUID from on-premises> -NotificationEmails admin@contoso.com
Start-MigrationBatch PublicFolderMigration

The batch syncs about once every 24 hours until you complete it. Wait for Synced with no failed requests.

7. Lock down on-premises (downtime starts)#

Re-run the sync script to catch new mail-enabled folders, then lock the source:

PowerShell
Set-OrganizationConfig -PublicFolderMailboxesLockedForNewConnections $true
Get-PublicFolder \

Once AD replication has caught up, Get-PublicFolder \ fails with Couldn't find the public folder mailbox. That's the expected sign that the lock is in place. Mail to mail-enabled folders queues until the end.

8. Complete, test, unlock#

Remove any on-premises entries returned by Get-MoveRequest or Get-PublicFolderMoveRequest, then run Complete-MigrationBatch PublicFolderMigration. The batch goes Synced, Completing, Completed; staying Synced for hours is normal. Point a few test users at the new hierarchy, check folders, permissions and posting in Outlook, then open it to everyone:

PowerShell
Set-Mailbox -Identity testuser@contoso.com -DefaultPublicFolderMailbox Mailbox1
Set-OrganizationConfig -RemotePublicFolderMailboxes $null -PublicFoldersEnabled Local

9. Finalize on-premises#

Mail sent to mail-enabled folders during the downtime is still queued. Microsoft's article includes a script that exports those queued messages as a backup; run it first, then point the folders at Exchange Online and mark the migration complete:

PowerShell
.\SetMailPublicFolderExternalAddress.ps1 -ExecutionSummaryFile:mepf_summary.csv
Set-OrganizationConfig -PublicFolderMailboxesMigrationComplete:$true -PublicFoldersEnabled Remote

The errors that stop the batch#

ErrorCauseFix
Cannot find a recipient that has mailbox GUID on New-MigrationBatchDirectory replication in Exchange Online hasn't caught up with the new public folder mailboxesWait about an hour and retry
Batch fails with transient errorsHierarchy GUID taken from Exchange OnlineRecreate the batch with the on-premises GUID
PublicFolderMailboxesLockedForNewConnections parameter not foundAD not prepared after a CURun /PrepareAD from the installed CU
Error: Dumpster of the Dumpster folder.Known migration issueStop the batch and start it again
Request was quarantined because of the following error: The given key wasn't present in the dictionary.A corrupt item the job can't copyStop the batch, find the folder in the migration report, move it to the primary public folder mailbox with New-PublicFolderMoveRequest, remove the move request, restart
No active public folder mailboxes were found at Complete-MigrationBatchMulti-domain forestFollow Microsoft's article for that error before completing
Jobs stalled or failing intermittentlyToo many concurrent jobsSet-MigrationEndpoint PublicFolderEndpoint -MaxConcurrentMigrations 30 -MaxConcurrentIncrementalSyncs 20 -SkipVerification

Also check (Get-PublicFolder -GetChildren "\NON_IPM_SUBTREE\DUMPSTER_ROOT").Count: more than 10,000 immediate subfolders there can make the migration fail.

Verify#

  • Run the same Export-CliXML snapshots in Exchange Online and compare folder counts, item counts and mail-enabled folders with the on-premises files.
  • Get-PublicFolderMailboxMigrationRequest | Get-PublicFolderMailboxMigrationRequestStatistics shows every request completed.
  • Users see the hierarchy in Outlook, and a test message to a mail-enabled folder arrives in Exchange Online.

Tips and gotchas#

  • Permissions on the root folder and \NON_IPM_SUBTREE\EFORMS REGISTRY, Send As and Send on Behalf don't migrate. Record them first and re-add them with Add-PublicFolderClientPermission, Add-RecipientPermission and Set-MailPublicFolder -GrantSendOnBehalfTo.
  • Every public folder mailbox in Exchange Online must serve the hierarchy (IsExcludedFromServingHierarchy False).
  • External mail to migrated folders bouncing with 5.7.13 or 5.4.1? Grant Anonymous CreateItems and check Directory-Based Edge Blocking.
  • Keep the on-premises public folder mailboxes for a few weeks: deleting them is irreversible.

References#

Written and checked against current Microsoft Learn documentation. Test changes with a pilot group before rolling them out to everyone, and if an admin center path has moved since, search for the setting name instead.

Spotted a mistake, or did this fix work differently for you? Email me or message me on LinkedIn — corrections are credited in the article.

Written by

Omer Eltayeb

Intune Subject Matter Expert in Cairo, Egypt, former Microsoft Cloud Solutions Architect, Microsoft Certified Trainer and Microsoft Innovative Educator Expert (2024–26) and Microsoft Elevate Educator Expert (2026–27). I share practical, step-by-step guides, study plans, scripts and toolkits for Microsoft Intune, Configuration Manager, Microsoft Entra ID, Microsoft Defender, Exchange and Microsoft 365 with the community.

Microsoft Certified Trainer (MCT) 2026Microsoft Innovative Educator Expert 2025–2026Microsoft Elevate Educator Expert 2026–2027ISC2 Certified Information Systems Security Professional (CISSP)Microsoft 365 Certified: Enterprise Administrator Expert (MS-102)