The process of migrating Public Folders is a complicated one unfortunately. Luckily, if you are migrating from Exchange 2013 or Exchange 2016 then Microsoft has made things a bit easier for you, this is still going to be a bit of a slog to complete, but much less so than migrating from legacy versions of Exchange.

Before we get onto the Migration we need to ensure that we hit the following migration prerequisites:

  • Exchange Version: Exchange 2013 all cumulative updates, Exchange 2016 all cumulative updates and Exchange 2019
  • Exchange Online Permissions: Mailbox have root permission to access public folder
  • Local Exchange Permissions: User have Admin privilege
  • Public Folder Mailbox size 50 GB have contain one or more folder have 50 GB
  • MRS Proxy service running on one of your local Exchange Servers


The migration process can be broken down into the following steps:

  1. Download the Migration Scripts
  2. Prepare your local server
  3. Prepare Exchange Online
  4. Create Migration files
  5. Create public folder mailboxes and single public folder and assign the root permission of a mailbox
  6. Start the migration
  7. Lock access to the old public folders
  8. Finish the Migration (Switchover to Exchange Online)
  9. Test
  10. Complete the Migration
Download the Migration Scripts

Download all of the following scripts -

I would recommend that you save them all in a folder called C:\PFScripts to make following this article easier.

Prepare the Local Exchange Server

Only the following versions of Exchange server are supported by these scripts

  1. Add your onmicrosoft domain to your local server New-AcceptedDomain -Name PublicFolderDestination_MigrationPF -DomainName "" -DomainType InternalRelay
  2. We need to rename any public folders whose name contains a backslash '\'
    1. Get-PublicFolder -Recurse -ResultSize Unlimited | Where {$_.Name -like "*\*" -or $_.Name -like "*/*"} | Format-List Name, Identity, EntryId

    2. If this comes back with any results simply rename the public folder without the backslash.
  3. Now we need to check for the existence of any previous successful or failed migration attempts.
    1. Get-OrganizationConfig | Format-List PublicFoldersLockedforMigration,

    2. If this command returns $true for any of the options then you need to run this to reset them
    3. Set-OrganizationConfig -PublicFoldersLockedforMigration:$false -
      PublicFolderMigrationComplete:$false -
      PublicFolderMailboxesLockedForNewConnections:$false -

  4. Let’s take a snapshot of the existing structure so we can verify the success of the migration afterwards
    1. Get-PublicFolder -Recurse -ResultSize Unlimited | Export-CliXML OnPrem_PFStructure.xml

    2. Get-PublicFolderStatistics -ResultSize Unlimited | Export-CliXML OnPrem_PFStatistics.xml

    3. Get-PublicFolder -Recurse -ResultSize Unlimited | Get-PublicFolderClientPermission | Select-Object Identity,User -ExpandProperty AccessRights | Export-CliXML OnPrem_PFPerms.xml

    4. Get-MailPublicFolder -ResultSize Unlimited | Export-CliXML OnPrem_MEPF.xml

    5. Put all the files generated above in the C:\PFMigration folder
Prepare Exchange Online

Open an Exchange Online Shell, connect to Exchange Online and then do the following:

  1. We need check that there are no existing migration requests
    1. Get-PublicFolderMigrationRequest | Get-PublicFolderMigrationRequestStatistics

    2. Get-MigrationBatch | ?{$_.MigrationType.ToString() -eq "PublicFolder"}

    If either of these commands returns anything, delete the existing requests
  2. We need to check that PAW is enabled
    1. Get-MigrationConfig
    2. Look under the features heading
    3. If you see can see PAW listed then carry on, if it is not enabled you will likely need to speak to office 365 support.
  3. In the Exchange Online EAC check that there are no existing public folder mailboxes, if there are delete them.
Generate the Migration Files

Open Exchange PowerShell on your local Exchange server, change the directory to C:\PFScripts run the following commands

  1. .\Export-ModernPublicFolderStatistics.ps1 PublicFolderstats.csv

  2. .\ModernPublicFolderToMailboxMapGenerator.ps1 -MailboxSize 25GB -MailboxRecoverableItemSize 1GB -ImportFile .\publicfolderstats.csv -ExportFile C:\PFMigration\map.csv

If you’ve previously done Exchange 2007 or 2010 Public folder migrations you’ll be relieved to learn you only need to generate these 2 files.

Create Public Folder Mailboxes

In Exchange Online, mailboxes act as the backbone for the Public Folder storage, we need to create these mailboxes before we can create public folders. Connect to Exchange Online PowerShell and run this script:

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

Start the migration

It’s time to get the migration started! From your Local Exchange Server open Exchange Shell, change directory to C:\PFscripts and run the following command

.\Sync-ModernMailPublicFolders.ps1 -Credential (Get-Credential) -CsvSummaryFile:sync_summary.csv

When prompted enter the login details for your Exchange Online admin account.

Now switch to Exchange Online PowerShell and do the following,

  1. $Source_Credential = Get-Credential domain\exchangeadmin
    (replacing the domain \ user name with your own)

  2. $Source_RemoteServer = ""
    (replacing the server name with the name of your MRS Proxy Server)

  3. Run this Script

    PfEndpoint = New-MigrationEndpoint -PublicFolder -Name PublicFolderEndpoint
    -RemoteServer $Source_RemoteServer -Credentials $Source_Credential
    [byte[]]$bytes = Get-Content -Encoding Byte C:\PFMigration\map.csv
    New-MigrationBatch -Name PublicFolderMigration -CSVData $bytes -SourceEndpoint
    $PfEndpoint.Identity -NotificationEmails

  4. Start the Migration

    Start-MigrationBatch PublicFolderMigration

Lock access to the old public folders

Now, we need to stop people who are using the existing on premise public folders from being able to access them. To do this open Exchange Shell on any of your Exchange servers

Set-OrganizationConfig -PublicFolderMailboxesLockedForNewConnections $true

This can take up to 2 hours to replicate around and take effect for all users.

Finish the Migration

Connect to Exchange Online PowerShell and run this command

Complete-MigrationBatch PublicFolderMigration


Before unlocking the new public folders for all users, I would recommend testing that the migration has completed successfully. To do this, assign yourself or some test users access to the new public folders

Set-Mailbox -Identity <test user> -DefaultPublicFolderMailbox <public folder mailbox identity>

Once you have confirmed everything looks ok you can unlock the public folders for all users

Set-OrganizationConfig -RemotePublicFolderMailboxes $Null -PublicFoldersEnabled Local

Complete the Migration

Finally, run the following two commands on your local Exchange server

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

And that’s it, you are finally done! If you are looking for an easier route to migrating Public Folders to Office 365 consider trying.

Easy migration with Kernel Migrator for Exchange

If you are looking for an easy method to migrate your public folders to Office 365, then you only need to use this tool which is a perfect choice to migrate public folder to any desired destination. Exchange Migration tool migrates public folders to Office 365 along with all its permissions and limits. Before starting the migration, it lets you run a pre-migration analysis and understand the time required for the migration. It also provides an option to undo the migration process if the migration was interrupted in midway due to any situation.

Let us go through the migration process performed by Kernel Migrator for Exchange for migrating Exchange 2013/2016/2019 public folders to Office 365.

  1. Open Kernel Migrator for Exchange software application. Click Add Project from the home screen to add a project. Now click on Add Public folders. Open Kernel Migrator for Exchange
  2. Provide a job name and click Next. Provide a job name
  3. Enter the source domain (Exchange 2013) login details. Validate those details with the Validate option. You can Use existing profile also and delegate owner rights to this user on public folder(s). After providing complete information, click Next. Enter the source domain
  4. Select required public folders from the retrieved list and then click Next. Select required public folders
  5. Provide the target domain (Office 365 account) details like user name and password. Validate them with the given option. Click Next. Provide the target domain
  6. Apply the filters like Message classes, Date range, etc. and click Next. Apply the filters
  7. Select the options to manage bad items and synchronization. Then click Next. Select the options to manage
  8. Provide the e-mail address to set notifications as per your need and click Next. set notifications
  9. Verify the details given in the summary and click Finish to start the migration. Finish the migration

Within minutes, migration of Exchange public folders to Office 365 is finishedand the migration status is shown.

Thus, you can perform migration of Exchange and Office 365 swiftly using Kernel Migrator for Exchange.