This post is about a recent migration of legacy public folders hosted on Exchange Server 2007 to modern public folders hosted on Exchange Server 2013.
How it all started
The public folder hierarchy had been in use since Exchange Server 2000 and the public folder size was approximately 1.2 TB. The legacy public folder migration was originally planned as part of a migration project for upgrading from Exchange Server 2007 to Exchange Server 2013. The original project plan included an interim move of legacy public folders to Exchange Server 2010. Reason being was that in the early days of Exchange Server 2013, the supported number of public folders and the overall supported size of legacy public folders was out of scope. Additionally, the public folder migration was handled by a single public folder move request and would have had an unforeseeable long outage of public folder access during finalization. Such an unforeseeable outage was not acceptable as public folders are an active part of the product production process.
The Exchange 2010 Story
The interim migration of legacy public folders to Exchange Server 2010 resulted in a disaster. Due to replication issues (content conversion issues, to be precise), not all content was replicated from Exchange Server 2007 to Exchange Server 2010. Moreover, due to the public folder database size being larger than 1TB, the replication state table of the Exchange 2010 database was corrupted. As a result, Exchange 2007 replication messages were accepted but not properly processed.
To make a long story short: the Exchange 2010 episode was rolled back and a new virtualized Exchange Server 2007 environment was built just for the purpose of hosting public folders.
The Exchange 2013 Story
Exchange Server 2013 was installed into the existing Exchange organization and mailboxes were moved from Exchange Server 2007. As part of the 2007/2013 coexistence scenario it turned out that you do not only have to configure public folder discovery mailboxes (see On-Premises Legacy Public Folder Coexistence for Exchange 2013 Cumulative Update 7 and Beyond), but also to set the PublicFolderDatabase attribute of Exchange 2013 mailbox databases as well. This was a configuration issue identified during the Exchange 2010 situation.
In the RTM days of Exchange Server 2013 the supported number of public folders was 100,000. One of the strategic goals after the Exchange Server 2010 disaster was "get rid of public folders." Public folder content that had been build up for more than 15 years within the company cannot just be deleted (keyword: compliance). Therefore, we had started to identify and isolate data per department or per user.
Users had used the public folder hierarchy as a personal mailbox archive when their primary mailbox reached a quota limit. Such data was simply moved to user archive mailboxes. Public folder data that could be grouped on a department or team level was migrated to shared mailboxes retaining the user permissions set on the folder structure within the public folder hierarchy.
This approach reduces the public folder size to approx. 0.5 TB. This is where the modern public folder migration kicked in.
The migration steps provided at TechNet (Use batch migration to migrate public folders to Exchange 2013 from previous versions) are straightforward. The following steps were been used during the successful migration of legacy public folders.
Download the most recent public migration scripts provided by the Exchange Team. Copy the files to your Exchange 2007 and Exchange 2013 server. I have used D:\Scripts folder on each server.
Step 1: Create a snapshot of the current Exchange 2007 public folders.
During this step, you export the legacy public folder hierarchy and permissions for comparison reasons after a successful migration.
Cmdlets executed on Exchange Server 2007:
Get-PublicFolder -Recurse -ResultSize Unlimited | Export-CliXML D:\Scripts\Legacy_PFStructure.xml -Encoding UTF8 -Force
Get-PublicFolderStatistics | Export-CliXML D:\Scripts\Legacy_PFStatistics.xml
Get-PublicFolder -Recurse -ResultSize Unlimited | Get-PublicFolderClientPermission | Select-Object Identity,User -ExpandProperty AccessRights | Export-CliXML D:\Scripts\Legacy_PFPerms.xml
Step 2: Prepare Public Folder Migration
Verify that the Exchange organization has not seen another public folder migration. Public folder migrations are controlled at the Exchange organization level.
Cmdlets executed on Exchange Server 2013:
Get-OrganizationConfig | fl PublicfolderslockedforMigration,PublicFolderMigrationComplete
PublicFoldersLockedForMigration : False
PublicFolderMigrationComplete : False
Export the legacy public folder statistics. This file is used for mapping the legacy public folders to modern public folder mailboxes.
Cmdlet executed on Exchange Server 2007:
.\Export-PublicFolderStatistics.ps1 -ExportFile D:\Scripts\PFStat.csv EX2007SERVER
Copy the PFStat.csv file from your Exchange 2007 server to your Exchange 2013 server. The following scripts maps the public folder hierarchy to modern public folder mailboxes trying to utilize not more than 10GB per mailbox. If your resulting CSV file contains more than 100 mailboxes, you have to increase the MailboxSize parameter. In my case, the modern public folder environment was set to utilize 1 dedicated hierarchy mailbox and 66 public folder content mailboxes.
Cmdlets executed on Exchange Server 2013:
.\PublicFolderToMailboxMapGenerator.ps1 -ImportFile D:\Scripts\PFStat.csv -ExportFile D:\Scripts\FolderToMailbox.csv -MailboxSize 10GB
.\Create-PublicFolderMailboxesForMigration.ps1 -FolderMappingCsv FolderToMailbox.csv -EstimatedNumberOfConcurrentUsers 500
Step 3: Starting Migration
Creating the public folder migration batch is a sensitive task. A public folder migration follows mostly the same rules as a regular mailbox migration batch. Especially when it comes to bad items. In an ideal world, you will not have any bad items that would prevent your migration batch from completing. However, legacy public folders are a wonderful source for various types of bad items.
Such types are:
- Mail enabled public folders from the early days of Exchange, not being cleaned up in previous migrations
- Mail disabled public folders still having their mail AD object in the MESO container
- Corrupted folder ACLs due to incorrect user account management
- Items that got corrupted over time, just because they are plain old and cannot be read at all
The assumption is that the legacy system public folders are the only bad items to expect. So we set the bad item limit to (5 + (PublicFolderDatabasesinOrg -1)). I have used a bad item limit of 50.
Cmdlets executed on Exchange Server 2013:
New-MigrationBatch -Name PFMigration -SourcePublicFolderDatabase (Get-PublicFolderDatabase -Server EX2007SERVER) -CSVData (Get-Content D:\Scripts\FolderToMailbox.csv -Encoding Byte) -NotificationEmails [Your Admin Email Address] -BadItemLimit 50
The created migration batch must be started.
Use the following PowerShell one-liner to verify the current state of the each migration user (public folder mailbox) of the public folder migration batch during synchronization.
Get-MigrationUser -BatchID PFMigration | Get-MigrationUserStatistics
In this time the migration batch performs an incremental synchronization every 24 hours and keeps 95% of the legacy public folder content synchronized with modern public folder mailboxes. Additions and deletions to the legacy public folders are synchronized.
Step 4: Finalization
The finalization requires downtime—therefore, the finalization must be performed during a scheduled maintenance. Legacy public folders are not accessible while the migration batch is finalizing. In my case, the finalization took about 3 hours.
I did not trust the migration process and wanted to be prepared for any user requesting "lost" data as one of the lessons learned during the mentioned Exchange 2010 public folder situation. Prior to finalizing the migration batch, I have dismounted the legacy public folder database and copied the database to file to a remote server location. This allows for connecting the database file to an EDB tool and for a manual "data restore".
Completing the migration batch does not fully switch the public folder hierarchy to modern public folders. At this point, you can still rollback your migration.
Lock the legacy public folders for migration using Exchange 2007 EMS and restart the legacy Exchange Information Store to honor the configuration change:
Verify that the legacy public folders are locked for migration by trying to access the public folder hierarchy using an Outlook client. You must receive client connection error. If you are still able to access legacy public folders do not progress with the migration. If you have more than one public folder server, each server connection must be verified.
Set the public folders to Remote and complete the migration batch using Exchange 2013 EMS:
Set-OrganizationConfig -PublicFoldersEnabled Remote
The PublicFoldersEnabled attribute might be set to Remote already. Just set it again.
When executing Set-OrganizationConfig on your Exchange 2007 server the cmdlet will configure the DisplayName property for Exchange recipients objects to "Microsoft Exchange". The Exchange Server 2013 default is "Microsoft Outlook". A Get-OrganizationConfig executed on Exchange Server 2013 will result in a warning.
While finalization is in progress, remember yourself the most important nature of an Exchange Administrator: patience. Do not try to intercept the process by restarting services or rebooting servers. Just wait.
When the migration batch is in Completed state, set the DefaultPublicFolderMailbox to your public folder mailbox holding the primary hierarchy and set the IsExcludedFromServingHierarchy attribute for all public folder mailboxes to $false.
Cmdlets executed on Exchange Server 2013:
Set-Mailbox -Identity TESTUSER -DefaultPublicFolderMailbox PFMailbox1
Get-Mailbox -PublicFolder | Set-Mailbox -PublicFolder -IsExcludedFromServingHierarchy $false
Start Outlook using a Testuser account and verify access to modern public folders. You can easily check the connection using the Outlook connection status window.
Step 5:The Point of No Return
If you are happy with the results, it is time to say Goodbye to the legacy public folder hierarchy.
Executing the following cmdlet using the Exchange 2007 EMS will instruct Exchange 2007 to remove the hierarchy and replica information from the public folder databases. This is a prerequisite to be able to remove the public folder databases at a later point.
Now we tell Exchange Server 2013 that public folders are local (from an Exchange 2013 point of view) using the Exchange 2013 EMS:
Set-OrganizationConfig -PublicFoldersEnabled Local
Verify that the PublicFolderMigrationComplete property has been properly set in Active Directory:
Get-OrganizationConfig | FL PublicFolderMigrationComplete
Verify that Exchange Server 2013 populates the user mailbox DefaultPublicFolderMailbox attribute with modern public folder mailbox names.
Get-Mailbox SOMERANDOMUSER | FL DefaultPublicFolderMailbox
Step 6: Post-Migration Task
After a successful migration, we need to clean up the coexistence settings.
- Clear PublicFolderDatabase attribute on Exchange 2013 mailbox database, if set. This can only be done using ADSIEdit, as the Set-MailboxDatabase cmdlet does not accept $null or an empty string as PublicFolderDatabase
- Set the RemotePublicFolderMailboxes property of the Exchange Organization configuration to be empty.
Set-OrganizationConfig -RemotePublicFolderMailboxes $null
Remove Exchange Server 2007
- Delete legacy Office Addressbook
- Delete legacy public folder database and storage group
- Delete Exchange Server 2007 discovery mailbox
- Delete legacy mailbox database and storage group
- Uninstall Exchange Server 2007
- Public Folders Migration Scripts, https://www.microsoft.com/en-us/download/details.aspx?id=38407
- On-Premises Legacy Public Folder Coexistence for Exchange 2013 Cumulative Update 7 and Beyond, https://blogs.technet.microsoft.com/exchange/2014/11/07/on-premises-legacy-public-folder-coexistence-for-exchange-2013-cumulative-update-7-and-beyond/
- Use batch migration to migrate public folders to Exchange 2013 from previous versions, https://technet.microsoft.com/EN-US/library/dn912663(v=exchg.150).aspx