If you would like to read the next part in this article series please go to Migrating Public Folders to Exchange 2013 (Part 2).
Now that Exchange 2007 SP3 RU10, Exchange 2010 SP3 and Exchange 2013 CU1 have been released, administrators can start deploying Exchange 2013 in a coexistence scenario with these two previous versions of Exchange.
Part of many transitions from Exchange 2007/2010 to 2013 will include the migration of Public Folders (PFs). Because of all the major changes made to PFs, discussed in the Exchange 2013 Preview - Public Folders article, legacy Exchange mailboxes are unable to access the PF hierarchy on Exchange 2013 servers. However, mailboxes on Exchange 2013 can connect to legacy PFs.
Unlike migrating PFs between previous versions of Exchange, PFs on Exchange 2013 and legacy PFs cannot coexist in an Exchange organization, which means that migrating PFs to Exchange 2013 is a one-time cut-over process.
Because legacy mailboxes cannot access PFs in Exchange 2013, it is recommended that all mailboxes are first moved to Exchange 2013 and only then PFs migrated.
The high level process for migrating Public Folders from Exchange 2007/2010 is as follows:
- Migrate user mailboxes to Exchange 2013 before migrating PFs;
- Snapshot current PF environment for comparison when migration is complete (folders, sizes and permissions);
- Create CSV file, manually or using scripts (Export-PublicFolderStatistics.ps1 and PublicFolderToMailboxMapGenerator.ps1). End result is a CSV file mapping PFs to new PF mailboxes;
- Create PF mailboxes using New-Mailbox –PublicFolder cmdlet;
- Migrate PF content using New-PublicFolderMigrationRequest cmdlet;
- Lock down Exchange 2007/2010 PFs for final migration using the following cmdlets:a. Set-OrganizationConfig –PublicFoldersLockedForMigration $True (Exchange 2010)b. Set-OrganizationConfig –PublicFolderMigrationComplete $True (Exchange 2013)
c. Set-PublicFolderMigrationRequest <name> -PreventCompletion $False (Exchange 2013)
d. Resume-PublicFolderMigrationRequest <name> (Exchange 2013)
- Test new PFs;
- Snapshot Exchange 2013 PFs and compare with Exchange 2007/2010 PF snapshots;
- Roll back, if necessary, by running Set-OrganizationConfig –PublicFoldersLockedForMigration $False and Set-OrganizationConfig –PublicFolderMigrationComplete $False;
- Remove Exchange 2007/2010 PFs and PF databases.
For this article I set up a lab with the following characteristics:
- Only one PF database on an all-in-one Exchange 2010 server;
- 307 PFs with approximately 10500 items in total;
- Although in this article I am migrating PFs from Exchange 2010 to 2013, the process for Exchange 2007 is identical;
- Exchange 2010 server name: AIO
- Exchange 2013 server name: AIO13
It is worth highlighting a few notions just in case you are not aware:
- Only Outlook 2007, Outlook 2010 and Outlook 2013 can access PFs;
- PFs cannot be accessed through Exchange 2013 OWA at this stage;
- There is no mailbox audit logging against PF mailboxes at this time;
- If the master hierarchy PF mailbox becomes unavailable, users can view but not write to PFs;
- It is not possible to change which PF mailbox is the master hierarchy mailbox;
- When you migrate PFs, PF rules are migrated along with the data and are kept as PF rules. They are not converted to mailbox rules.
Prepare for Migration
Before we start migrating PFs across to Exchange 2013, there a number of recommended steps that need to be performed beforehand.
It is recommended to first create a “snapshot” of all the current PFs by exporting to CSV files their structure, permissions and statistics. This will allow us to later compare this snapshot with the end result in Exchange 2013 at the end of migration, simply for verification purposes.
So, on the Exchange 2010 server, we run the following three cmdlets:
Figure 1.1: Public Folder Snapshot
The first cmdlet takes a snapshot of the original PF structure:
Get-PublicFolder -Recurse | Export-CSV C:\PFs\2010_PFStructure.csv -NoTypeInformation
The second cmdlet takes a snapshot of the PF statistics such as item count, size, owner, etc.:
Get-PublicFolder -Recurse | Get-PublicFolderStatistics | Export-CSV C:\PFs\2010_PFStatistics.csv -NoTypeInformation
Finally the third cmdlet takes a snapshot of all the PF permissions:
Get-PublicFolder -GetChildren | Get-PublicFolderClientPermission | Select Identity, User -ExpandProperty AccessRights | Export-CSV C:\PFs\2010_PFPerms.csv -NoTypeInformation
Note that I am not using –ResultSize Unlimited as I know I have less than 1000 PFs. I also like to use –NoTypeInformation (or simply –NoType) to automatically remove that first row with information that the Export-CSV cmdlet puts on CSV files by default.
Still on Exchange 2010 server, we now need to make sure there is not a record of any previous PF migration. If there is, we need to set that value to False because if it is set to True the migration request will fail.
Figure 1.2: Public Folder Migration Record
If either PublicFoldersLockedforMigration or PublicFolderMigrationComplete are set to True, run the following cmdlet to set them to False:
Set-OrganizationConfig –PublicFoldersLockedforMigration $False –PublicFolderMigrationComplete $False
In this case, we will need to wait for Exchange to detect the new settings, which might take several minutes. To speed up this process, we can restart the Microsoft Exchange Information Store service.
Now we move onto Exchange 2013. Here, we need to make sure there are no existing PF migration requests as well. This is only required if there are any existing migration requests in the pipeline. Run the following cmdlet to remove any existing PF migration requests:
Figure 1.3: Removing Public Folder Migration Requests
Another pre-requite is that there are no PFs on any Exchange 2013 server. These will be automatically created as part of the migration process. Run the following cmdlet to make sure there are no PFs and no PF mailboxes on 2013:
Figure 1.4: Checking for Public Folder and Public Folder Mailboxes
Because in this case this is an out-of-the-box deployment of Exchange 2013, there are no PFs at all. If you happen to have created any, then you need to remove them before you proceed.
Map Public Folders
The following procedures can be skipped and you can go straight to manually creating a CSV file which tells Exchange which PF mailbox to use for each PF. However, I strongly recommend you follow these steps, if not at least to understand the overall process and to help you in producing the final CSV.
The first step is to create a CSV file which maps PF name-to-folder size. This CSV file will contain two columns, FolderName and FolderSize (displayed in bytes) and will be used later to decide on how many PF mailboxes to use so that each one of them falls under a specified (by you) size limit.
Copy the files Export-PublicFolderStatistics.ps1 and Export-PublicFolderStatistics.strings.psd1 from your Exchange 2013 server (<install_dir>\Exchange Server\V15\Scripts\) into your Exchange 2010 server, and then, from the 2010 server, run the script to generate the mapping file. The parameters to use with this script are:
.\Export-PublicFolderStatistics.ps1 <Folder to size map file path> <Source server>
- Folder to size map file path: the file name and path where you want the CSV file to be created. You will need to copy this file into your Exchange 2013 server;
- Source server: the name of the Mailbox server where the public folder hierarchy is hosted.
Figure 1.5: Creating Name-to-Folder Mapping
Once complete, the CSV file will list all your PFs and their corresponding size (in bytes):
Figure 1.6: Public Folder Sizes
Now we run the PublicFolderToMailboxMapGenerator.ps1 script on Exchange 2013 server to create the PF folder-to-mailbox mapping file based on the CSV we just generated. The new CSV is used to create the correct number of PF mailboxes on Exchange 2013, as explained earlier.
For simplicity, I copied the PFmapNameToSize.csv file we generated on the previous step into the C:\PFs\ folder on the Exchange 2013 server as well as the PublicFolderToMailboxMapGenerator.ps1 and PublicFolderToMailboxMapGenerator.strings.psd1 files from the Exchange 2013 scripts folder.
This script is run with the following parameters:
\PublicFolderToMailboxMapGenerator.ps1 <Maximum mailbox size in bytes> <Folder to size map path> <Folder to mailbox map path>
- Maximum mailbox size in bytes: the maximum size you want to set for the new PF mailboxes. However, you can use the standard size suffixes, as shown in the example below. Be sure to allow for expansion so the PF mailboxes have room to grow;
- Folder to size map path: the file name and path of the CSV file we generated earlier when running the Export-PublicFolderStatistics.ps1 script;
- Folder To mailbox map path: the file name and path of the folder-to-mailbox CSV file that will be generated by this script.
Figure 1.7: Creating Name-to-Size Mapping
In this case, I chose a maximum size of 100MB for any PF mailbox. However, because all my PFs together take less space than that, the script came out with a single PF mailbox, Mailbox1, under which it places all PFs:
Figure 1.8: Public Folder-to-Mailbox Mapping
If I had specified a PF mailbox size of 100KB instead of 100MB, just for illustrative purposes, several more PF mailboxes would be created. In this case, Exchange would spread PFs across all of them in order to achieve the maximum size limit I specified (this is where the first CSV file is used):
Figure 1.9: Public Folder-to-Mailbox Mapping 2
However, because in my scenario we are talking about a (imaginary) multinational organization where each top-level PF will be hosted in different servers across the globe, I want to place all the Asia PFs in a PF mailbox, all the America PFs in another PF mailbox, and so on. This will allow me to place the Asia PF mailbox in a database hosted by a Database Availability Group (DAG) in Asia, the America PF mailbox in a database hosted by a DAG in America, etc. Obviously, if all PFs for America take up 120GB of space, for example, I can split them into multiple PF mailboxes and even multiple databases.
To achieve this, and so we can meet the organization’s requirements, we can manually edit this CSV file. Alternatively, since we now know its format and how it is used, we can skip the previous steps and manually create this CSV file from scratch.
In my case, I updated the TargetMailbox field with the names of the PF mailboxes I want to use. Remember that, at this stage, there are no PF mailboxes created yet.
The end result is as follows (note that most lines have been hidden so you can see the overall distribution of PFs):
Figure 1.10: Final Public Folder-to-Mailbox Mapping
As explained before, this CSV file is used to determine the mapping between the source hierarchy and the destination mailbox. It contains “only” the top-level folders because child folders under the top-level folders are automatically migrated. As such, if a new child folder is added, it is migrated during the process. If a new top-level folder is created, it will be created in the mailbox that contains the writable copy of the hierarchy.
The reason why Exchange included child PFs in this CSV (Figure 1.9), is because of the very low size limit I set. Otherwise, only top-level folders would be referenced.
This CSV is critical to ensure each PF and each PF mailbox is placed in the appropriate geographic location, ensuring they are near the target users. This is more important than ever because now we can only have one active PF in the entire organization, meaning that if a user in Europe wants to access a PF in America, he/she will be accessing the PF in America and not a local copy as before.
You can also see that I am creating a PF mailbox dedicated to the PF hierarchy, which is not required.
Create Public Folder Mailboxes
In this step we create the required PF mailboxes to hold all the PFs being migrated. We have to create a PF mailbox for all the names we mentioned in the TargetMailbox field of the mapping file otherwise Exchange will try to copy PFs to a PF mailbox that does not exist.
Remember that the first PF mailbox that we create will be the master hierarchy mailbox. This first PF mailbox, and only this, must be created in HoldForMigration mode. This parameter prevents any user, with the exception of the Microsoft Exchange Mailbox Replication service process, from logging into a PF mailbox.
We also create all PFs but exclude them from serving hierarchy so that e-mails are not delivered to them during this phase and to prevent users from accessing them.
To create all the necessary PF mailboxes, we use the New-Mailbox cmdlet:
New-Mailbox -PublicFolder PF-Hierarchy –Database DB01 -IsExcludedFromServingHierarchy $True –HoldForMigration
New-Mailbox -PublicFolder PF-Asia –Database DB01 -IsExcludedFromServingHierarchy $True
New-Mailbox -PublicFolder PF-America –Database DB02 -IsExcludedFromServingHierarchy $True
New-Mailbox -PublicFolder PF-Europe –Database DB03 -IsExcludedFromServingHierarchy $True
New-Mailbox -PublicFolder PF-Antartica –Database DB04 -IsExcludedFromServingHierarchy $True
New-Mailbox -PublicFolder PF-Australia –Database DB05 -IsExcludedFromServingHierarchy $True
New-Mailbox -PublicFolder PF-Africa –Database DB06 -IsExcludedFromServingHierarchy $True
If we now check the Exchange Admin Center, we should be able to see all the PF mailboxes we have just created:
Figure 1.11: Public Folder Mailboxes in the EAC
However, there are no PFs yet as these will be created automatically during the migration process:
Figure 1.12: Public Folders in the EAC
In the first part of this article series, we had a look at the overall process of migrating Public Folders from Exchange 2007/2010 to Exchange 2013. We started the process by preparing for the migration and by mapping which Public Folders will go into each Public Folder mailbox. In the second and final part we will start and finalize the migration, and see how we can roll back the process if needed.
If you would like to read the next part in this article series please go to Migrating Public Folders to Exchange 2013 (Part 2).