Migrating from Exchange 2010 to 2013 – part 5

#en, #exchange edit this page

Welcome to the last post in this series, we did migrate all mailboxes in part 4, the only thing that is still missing is public folder. So let’s go ahead and migrate legacy public folders over to modern public folders.

Modern Public Folders, huh?

Public folders have been around for quite a while now, and for some time they have been written off, even by Microsoft. Exchange 2007 RTM’d without management features, 2010 came along with no real improvements to replication and high availability.

Everything changed, Exchange 2013 introduces the shiny, new “Modern Public Folders”. This shows that the Exchange Team is actually listening to customers, this, and the availability of public folders in Exchange Online (Exchange Team Blog) tells us that modern public folders are here to stay. So what’s changed?

No more public folder databases, modern public folders are stored in the mailbox database, within special public folder mailboxes. This gives the administrator more flexibility (think DAG) and reduces a lot of the additional complexity that came with managing PF replication. Other nice side effects are that clients do not need to connect to the mailbox servers anymore, CAS is now able to handle ALL incoming connections.

The hierarchy is stored within a root public folder mailbox but every public folder mailbox has a read-only copy, so all clients get quick access to it. The root mailbox can be shown using the following cmdlet:

Get-OrganizationConfig | select RootPublicFolderMailbox


Once you are ready to migrate public folder to Exchange 2013, head over to Microsoft’s Download Center and download the Public Folder Migration Scripts. I downloaded these scripts to the Exchange 2010 server, as they will be run there. The first script to run is Export-PublicFolderStatistics.ps1, it takes to parameters as input, the first one is a filename the second one is your Exchange 2010 mailbox server.

.\Export-PublicFolderStatistics.ps1 sizemap.csv EX14.tomt.local

This script creates a file called sizemap.csv in the current directory, this file contains public folder statistics gathered from the server EX14.tomt.local. It’s actually a simple list of public folder names and their respective sizes in bytes.


The second script, PublicFolderToMailboxMapGenerator.ps1 reads the output file generated by the first one, and takes two additional parameters. The first parameter is the maximum mailbox size in bytes, then comes the sizemap.csv generated by the first script, the last parameter specifies a new file, which will contain a public folder to mailbox mapping based on the maximum mailbox size parameter.

.\PublicFolderToMailboxMapGenerator.ps1 1073741824 sizemap.csv mailboxes.csv

This example specifies a 1GB mailbox limit, it reads the sizemap.csv from the previous script, and creates a new mailbox to home public folders every time the mailbox size will reach 1GB.


As my little lab does not have a huge public folder structure, everything will be placed into the first mailbox. Note that I changed the name of the first “TargetMailbox” as the default was something like “Mailbox1”.

So now that we have created the mailboxes.csv file, we need to copy it over to the Exchange 2013 mailbox server. In the next step we are going to import the mailboxes.csv file and create the target public folder mailboxes with a little bit of PowerShell:

Import-Csv .\mailboxes.csv | select -expand TargetMailbox | foreach {New-Mailbox -Name $_ -PublicFolder -HoldForMigration:$True -IsExcludedFromServingHierarchy:$true}

The two parameters HoldForMigration and IsExcludedFromServingHierarchy are used to prevent users from accessing the public folder mailbox for now. To verify that the mailboxes have actually been created use the following cmdlet:

Get-Mailbox –PublicFolder


Ok, so now that we have created the target mailboxes we can go ahead and start moving data. Again, we will need the mailboxes.csv file, as the New-PublicFolderMigrationRequest cmdlet takes it as input:

New-PublicFolderMigrationRequest -SourceDatabase (Get-PublicFolderDatabase -Server ex14.tomt.local) -CSVData (Get-Content .\mailboxes.csv -Encoding Byte)

In this example I am getting public folder database information from the server EX14.tomt.local and then reading the content of mailboxes.csv, which has to be in the current location. As the name implies, a new Public Folder Migration Request is generated, it copies data at about two to three GB per hour. The request is created with the PreventCompletion parameter set to $true, that means, once the data has been copied, the request will be AutoSuspended.

Users should not have noticed anything about this public folder migration until now, they continue working on the 2010 public folder as usual. Before we can complete the public folder migration request, though, we will need to block user access to the legacy public folders. We will need some time to synchronize the already moved data with latest changes during this window of downtime.

So once you’ve informed your users, we are going to prevent access to legacy public folders, remember that because of HoldForMigration:$true, we are also preventing access to the modern public folders!

Set-OrganizationConfig -PublicFoldersLockedForMigration:$true

This setting prevents users to access public folders, be sure to allow some time for it to replicate if you have more than one public folder database. Now that no one is able to make changes to the legacy public folders, we can go ahead and set the PreventCompletion flag to $false, and then resume the public folder migration request to finally move all data.

Set-PublicFolderMigrationRequest -Identity \PublicFolderMigration -PreventCompletion:$false
Resume-PublicFolderMigrationRequest -Identity \PublicFolderMigration

Once this is done, it is recommended to test access to modern public folders with a few users, before allowing everybody to make changes again. This is the last point in time where you do have a way back without data loss!

To test access to the modern public folders, we use the following cmdlet:

Set-Mailbox –Identity user1 –DefaultPublicFolderMailbox PFMailbox001

This overrides the IsExcludedFromServingHierarchy and allows the user user1 to access public folders on the new Exchange 2013 server. Outlook Connection Status will show something like this:


If everything is fine, we can finally remove the IsExcludedFromServingHierarchy flag and set the PublicFolderMigrationComplete property to $true.

Get-Mailbox -PublicFolder | Set-Mailbox -PublicFolder -IsExcludedFromServingHierarchy:$false
Set-OrganizationConfig -PublicFolderMigrationComplete:$true

Ok, one last thing: You may have noticed that the Proxy Server in the screenshot above shows the external server name for the connection to Exchange Public Folders. This is due to a bug in Outlook, before a fix becomes available, make sure internal clients can access the external hostname by creating a split DNS record. There is a KB article available, here.

Nice, that completes this series on migrating Exchange 2010 to Exchange 2013. Thanks for following along :)


so long, see you next time!