Exchange 2010 Public Folder migration

So far, all my customers had decommissioned Public Folders in the Exchange 2010 timeframe, all migration I did have never included Public Folders, until now. The Exchange 2010 (hybrid) to Exchange 2016 (hybrid) migration included approx. 1000 mailboxes and maybe 100 Public Folders (in only one Public Folder database) but they were real Public Folders with real users using them 😊

Migrating Public Folders looks easy, it’s a matter of gathering information regarding the Public Folders and its permissions, copying that over to a Public Folder database and keeping the contents in sync and when you’re ready finalize the migration. Or in steps:

  1. Downloading scripts from Microsoft from
  2. Preparing the organization for public folder migration.
  3. Generating CSV files using the Microsoft scripts.
  4. Creating public folder mailboxes in Exchange 2016 databases.
  5. Starting the migration, and waiting for initial synchronization to complete.
  6. Locking the public folders for final migration (this requires an outage, usually of at least an hour, but longer for very large environments).
  7. Finalize the public folder migration.
  8. Testing modern public folders, and then unlocking them for access by users (the outage is now over).

I know there are several other blogs available on this topic, but this way I also have my own reference available.

Note. Migrating Public Folders can only be done when all mailboxes are migrated to Exchange 2016. Mailboxes still on Exchange 2010 cannot access Public Folders on Exchange 2016!

Take snapshot of existing Public Folders on Exchange 2010

The first step is to take a snapshot of the existing environment, both the Public Folders, their statistics and permissions. Basic PowerShell and the output is exported to an XML file:

Get-PublicFolder -Recurse | Export-CliXML C:\PFMigration\Legacy_PFStructure.xml
Get-PublicFolderStatistics | Export-CliXML C:\PFMigration\Legacy_PFStatistics.xml
Get-PublicFolder -Recurse | Get-PublicFolderClientPermission | Select-Object Identity,User -ExpandProperty AccessRights | Export-CliXML C:\PFMigration\Legacy_PFPerms.xml


Most customers will run into issues with naming of their Public Folders. Customers tend to use strange characters in the Public Folders names (back slash, forward slash) and these are not supported. Hence, they should be replaced. To retrieve a list of all Public Folders with a back slash or forward slash in their name, you can use the following command:

Get-PublicFolderStatistics -ResultSize Unlimited | Where {($_.Name -like "*\*") -or ($_.Name -like "*/*") } | Format-List Name, Identity

You can use any tool you like to change the name, depending of the number of Public Folders of course. If you have 300,000 Public Folders you won’t use the Exchange Management Console to changes names of Public Folders (well, I cannot imagine you would).
Check for any previous migration attempts in your Exchange environment:

Get-OrganizationConfig | Format-List PublicFoldersLockedforMigration, PublicFolderMigrationComplete

Both values should have a value of False:

PF Locked for Migration

You can (should) use the Get-MigrationBatch cmdlet on Exchange 2016 (!) to see if there are any previous migration batches for Public Folders. If there are, delete them using the Remove-MigrationBatch cmdlet before continuing.

Generate the CSV files

The next step is to export the Public Folder statistics using the scripts downloaded from the Microsoft site. This will create a CSV file which is later used to map it to one or more Public Folders mailboxes. Run the following command on the Exchange 2010 server:

.\Export-PublicFolderStatistics.ps1 C:\PFMigration\PFStatistics.csv


The PublicFolderToMailboxMapGenerator scripts is used to create a mapping file. This maps the output of the previous command to one or more Public Folder mailboxes.
For this, you need to set the maximum size of a Public Folder mailbox. For example, to use a maximum size of 30GB, the value (in bytes) would be 32212254720. So, for a 30GB Public Folder mailbox you can use the following command:

.\PublicFolderToMailboxMapGenerator.ps1 32212254720 C:\PFMigration\PFStatistics.csv C:\PFMigration\folder-to-mailbox.csv


Create the Public Folder mailboxes in Exchange 2016

The Public Folder database(s) in Exchange 2016 are created using the Create-PublicFolderMailboxesForMigration.ps1 script. This script takes the mapping file that was created in the previous step, and it takes the estimated number of concurrent users. In my environment the number of concurrent users is approx. 900, so the command will be:

.\Create-PublicFolderMailboxesForMigration.ps1 -FolderMappingCsv C:\PFMigration\folder-to-mailbox.csv -EstimatedNumberOfConcurrentUsers:900


This will create a mailbox called Mailbox1 in a random Exchange 2016 database. If you want to use a specific database, you can edit the Create-PublicFolderMailboxesForMigration.ps1 script and add the -Database parameter to the New-Mailbox command.


Public Folder Migration Batch

At this point everything is in place for the Public Folder migration. The Public Folder database has been created, the Public Folders are created in this Mailbox and the permissions are set. A migration batch can be created using the following command on the Exchange 2016 server:

New-MigrationBatch -Name PFMigration -SourcePublicFolderDatabase (Get-PublicFolderDatabase -Server ) -CSVData (Get-Content -Encoding Byte) -NotificationEmails

This would translate to something like:

New-MigrationBatch -Name PFMigration -SourcePublicFolderDatabase PF01 -CSVData (Get-Content “C:\PFMigration\folder-to-mailbox.csv” -Encoding Byte) -NotificationEmails

Start the migration batch using the Start-MigrationBatch cmdlet:


It is possible to use the Get-PublicFolderMailboxMigrationRequest to get more information regarding the migration from Exchange 2010 to Exchange 2016:


You can see this migration batch in the Exchange Admin Center as well (under Recipients | Migration).

Exchange Admin Center

When you click the View Details option, all details regarding the migration, including the number of Public Folders, sizes, performance etc. will be downloaded as a text file.

Migration Status Report

To get more information regarding the batch you can also use the Get-PublicFolderMailboxMigrationRequest in combination with the Get-PublicFolderMailboxMigrationRequest Statistics command. This also gives a lot of information, and using the Select parameter you can only show the information you’re interested in. For example:

Get-PublicFolderMailboxMigrationRequest | Get-PublicFolderMailboxMigrationRequestStatistics | Select StartTimeStamp, CompleteAfter,BytesTransferred, ItemsTransferred, PercentComplete,Message


The ItemsTransferred value can be compared against the ItemsCount value when running Get-PublicFolder -Recurse | Get-PublicFolderStatistics command on the old Exchange 2010 server. This should closely match.

Finalize the Public Folder migration

All users still connect to the old Public Folders in Exchange 2010 and all changes are replicated to the Public Folders in Exchange 2016. The last stop in the migration is finalizing. In this step the Public Folders in Exchange 2010 are closed (users are disconnected) and the remaining contents are synchronized with Exchange 2016.

Be aware that this automatically means downtime for users. I typically recommend finalizing migrations off business hours. Since finalizing Public Folder migration can take quite some time (and this is unpredictable) I recommend starting this on Friday night.

The migration batch is now completed, and the new Public Folders in Exchange 2016 can be tested. Once ok the migration is finalized, and all users can connect to Public Folders in Exchange 2016. This is fully transparent for users, so no need to do anything on the client side.

To lock the Public Folders for migration, change the organization configuration and complete the migration batch, use the following commands:

Set-OrganizationConfig -PublicFoldersLockedForMigration:$true
Set-OrganizationConfig -PublicFoldersEnabled Remote

It can take some time before the previous commands are activated. When not fully active and continue with the Complete-MigrationBatch cmdlet, you will receive an error message stating:

Before finalizing the migration, it is necessary to lock down public folders on the legacy Exchange server (downtime required). Make sure public folder access is locked on the legacy Exchange server and then try to complete the batch again.


You can speed up this process by restarting the Information Store on the Exchange 2010 server (although difficult when running multiple Exchange 2010 servers).

Continue with the following cmdlet to complete the migration batch:

Complete-MigrationBatch PFMigration

To test the new Public Folders, you can enable it for a test mailbox using the following command:

Set-Mailbox -Identity -DefaultPublicFolderMailbox

In our environment, the mailbox identity is Mailbox1. You should check for the following:

  • View hierarchy
  • Check permissions.
  • Access content
  • Create and delete public folders.
  • Post content to and delete content from a public folder.

If all is well, you can finalize the migration using the following commands:

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


Outlook clients will now (seamlessly) connect to the new Public Folder infrastructure on Exchange 2016. Outlook will use Autodiscover to retrieve Public Folder mailbox information, so it can take some time (again) before this is picked up correctly. You can see this when running the Test E-mail Autoconfiguration option in Outlook (2010 in this example):



When moving from Exchange 2010 to Exchange 2016 you have to move Public Folders too. Starting in Exchange 2013, Microsoft introduced the concept of Modern Public Folders. Migrating to Modern Public Folders is not that difficult, but it needs proper preparation.

In our scenario we had issues with Public Folder names (strange unsupported characters) and Public Folders that were no longer in use. These can be fixed or removed before the actual migration takes place.

Another issue we ran into was that it took a long time before all clients discovered that Public Folders had moved to a new environment. Sometimes up to 48 hours (don’t know why and how). When this happens users cannot open Public Folders and start logging tickets at the Servicedesk. The only thing I could say at that point is “be patient”.

Other than that the migration went smooth, all clients (Outlook 2010 and 2016, mailboxes in Exchange 2016 and Exchange Online) were able to access the Public Folders after the migration.

More information


Exchange 2016 End of (mainstream) support

As you should (must) know, Exchange 2010 support will end this October. At that point, Microsoft will stop all support for Exchange 2010, including all security fixes. If you are still running Exchange 2010, you must act now and start moving to Exchange 2016 or to Office 365. For an Exchange 2010 to Office 365 migration I have written a couple of blogs before:

Moving from Exchange 2010 to Office 365.

Moving from Exchange 2010 to Office 365 Part II.

But what most people don’t realize is that Exchange 2016 mainstream support will also end this October. From that point forward, Exchange 2016 will be in extended support. This means no more Cumulative Updates and only Security Updates will be released when there updates are marked as ‘critical’.

Note. There’s no direct upgrade path from Exchange 2010 to Exchange 2019, so if you want to follow this route, you must move to Exchange 2016 first, followed by a migration to Exchange 2019.

If you move to Office 365 and have moved all your Mailboxes to Exchange Online, things are getting interesting. In this situation, you still need at least one Exchange server on-premises for management purposes. Microsoft supplies a free Exchange 2016 hybrid license for this situation (there is no free Exchange 2019 hybrid license!), and Microsoft is committed to support this configuration. At least until the moment a final solution is delivered by Microsoft to remove that last Exchange server from your on-premises organization. According to Microsoft, “this does not increase your risk profile in any way” as stated in their article “Exchange Server 2016 and End of Mainstream Support”.
If you still have mailboxes on-premises, the Microsoft recommendation is to move to Exchange 2019. Mainstream support for Exchange 2019 will end on January 1st, 2024, and extended support for Exchange 2019 will end on October 14, 2025 (this is the same date as end of extended support for Exchange 2016).

What to do

  1. If you are still on Exchange 2010, I would urge you to move to Exchange 2016 as soon as possible. Mainstream support for Exchange 2016 will stop this October, but according to Microsoft you are still safe since Security Updates will be released when needed. There’s no direct need to upgrade to Exchange 2019 at this moment, but this is something you must consider the upcoming time. I do know customers however that only want products that are in mainstream support, so if you are in this boat you must move to Exchange 2019 of course.
  2. If you are running Exchange 2013, you must start moving to Exchange 2019 anytime soon for optimal support and skip Exchange 2016.
  3. If you are in an Exchange 2016 hybrid scenario and all your mailboxes are in Exchange Online, you are safe to stay in this situation until Microsoft releases a final solution for that dreaded last Exchange server on-premises for management purposes.
  4. If you are in Exchange 2016 hybrid and you still have mailboxes on-premises, you must move this to Exchange 2019 hybrid to stay in a supported configuration. Please keep in mind that Microsoft only supports the version n-1 in a hybrid scenario, which means automatically Exchange 2019 after this October.



Office 365 Groups not showing up in Outlook 2016

I have had this annoying issue with Office 365 Groups (Groups, not Teams). In our IT team we have several Office 365 Groups. Some users do see these groups in Outlook 2016 almost immediately, other users do not see anything (I’m in this group). When I select Browse Office 365 Groups in Outlook, I see an error message saying We can’t show you group right now. Make sure Outlook is connected and try again as shown in the following screenshot:

we cant show you right now

In Office 365 Teams there are the HiddenFromExchangeClients and HiddenFromAddressListsEnabled properties (see the Hiding Office 365 Groups Created by Teams from Exchange Clients article from Tony Redmond for more information) , but this is only Office 365 Groups and not an Office 365 Team. And both properties are set to FALSE, so this is not the case.

I am using Office 365 ProPlus Click-to-Run which checks Exchange Online first for Autodiscover purposes, but then I realized I had been experimenting with some registry keys to change Autodiscover behavior. When checking the registry, I found the ExcludeExplicitO365Endpoint DWORD set to 1 as shown in the following screenshot:


So, Autodiscover checks on-premises Exchange server and is redirected to Office 365 for Exchange Online information. Unfortunately, this does not retrieve any information regarding Office 365 groups. After changing this value to ‘0’, Autodiscover starts with Office 365 and does retrieve the correct Office 365 Groups information.

Related to this, there are also scenarios where Outlook does not detect Office 365 groups using Autodiscover where the (primary) SMTP address of the Office 365 group is not correct. For example, where the SMTP address of the group is (for example) You can change the primary address of the group using the following command in Exchange Online PowerShell:

Set-UnifiedGroup Alias -PrimarySmtpAddress

Or when you want to add the SMTP address as a secondary address:

Set-UnifiedGroup IT-Calendar -EmailAddresses @{add=""}

This should also solve the problem.

Azure AD Connect versions

Be honest, how often do you check the software versions on your Azure AD connect server? I have to admit, Exchange is not an issue, this is updated regularly, but Azure AD Connect is a different story. At the moment of writing my Azure AD Connect version is running (installed on December 31, 2019 so more than 6 months ago) while version is already available for some time now (source: Azure AD Connect: Version release history). And although Azure AD Connect supports auto upgrade (Check with the Get-ADSyncAutoUpgrade cmdlet), not all updates of Azure AD Connect support auto upgrade and thus need to be upgraded manually.

Azure AD Connect older versions

It is important to have a look at the versions of Azure AD Connect, I was bit surprised (but can totally understand) to read the following on the Microsoft site:

“Starting on November 1st, 2020, we will begin implementing a deprecation process whereby versions of Azure AD Connect that were released more than 18 months ago will be deprecated. At that time we will begin this process by deprecating all releases of Azure AD Connect with version (which was released on 4/24/2019) and older, and we will proceed to evaluate the deprecation of older versions of Azure AD Connect every time a new version releases.”

You can download the latest versions of Azure AD Connect from After starting the Azure AD Connect package, enter the global tenant admin credentials and follow the wizard.

Upgrade Azure AD Connect

The upgrade should be finished in a minute or two.

Starting with Azure AD Connect version Microsoft implemented the Azure AD Connect sync V2 endpoint API (public preview) which will improve performance to Azure AD synchronization. You can enable the new endpoint using the following commands in a PowerShell window on the Azure AD Connect server (elevated permissions):

Set-ADSyncScheduler -SyncCycleEnabled $false
Import-Module 'C:\Program Files\Microsoft Azure AD Sync\Extensions\AADConnector.psm1'
Set-ADSyncAADConnectorExportApiVersion 2
Set-ADSyncAADConnectorImportApiVersion 2
set-ADSyncScheduler -SyncCycleEnabled $True

Azure AD Connect v2 endpoint

In the first screenshot you can also see the Azure AD Password Protection proxy. This was installed on December 17, 2019 and the version installed is This is also the latest version, which you can check on Azure AD Password Protection agent version history.

The Azure AD Password Protection proxy also supports auto upgrade, you can check the settings using the Get-AzureADPasswordProtectionProxyConfiguration cmdlet on the Azure AD Connect server.

More information

ExoPrise Cloud Monitoring solution

When you are running an on-premises IT environment you most likely have some kind of monitoring solution. If something goes wrong in the infrastructure you are notified almost immediately, and you can take appropriate action.

Things are different when using cloud services. Your services are running in a datacenter somewhere else, controlled by another organization and with an internet connection (that sometimes can be unreliable).

For a customer I checked out ExoPrise, a SaaS (Software as a Service) based cloud monitoring solution. With surprising results.

ExoPrise private site

Exoprise is a cloud monitoring solution which is offered as a SaaS solution. This means Exoprise is running in a datacenter somewhere, and you have a subscription for using the services. Because it is a SaaS solution, installing and configuring the monitoring solution is just a matter of minutes.

Exoprise is running in a datacenter somewhere, but when using Exoprise you configure your own private site. A private site is a WIN32 service running on a Windows server in your own environment. From this private site, cloud services are monitored. From an end-user perspective, the private site has the same user experience as your local users have.

You can install and configure multiple sensors in your private site. Each service has its own sensor, there are sensors for Exchange Online, Microsoft Teams (Messages and A/V), Skype for Business, Free/Busy, ADFS, OneDrive, SSLCheck, Amazon, Google, Salesforce …. Tons of sensors are available.

When configured, a sensor performs synthetic transactions against the cloud service. For example, the Exchange Online sensor looks at the average logon time, message transfer speed and network latency. The results are shown graphically for your own sensor, but because it is a SaaS solution Exoprise can compare your results against the results of the rest of the world which they call ‘crowd’. This is shown in the following screenshot, the lower line is my own sensor, the upper (thinner) line is the crowd average.

With all this working from home due to the Covid-19 crisis a lot of organization have been implementing Microsoft Teams rapidly. As an admin you want to know you Teams is performing from your local environment. When configuring a Teams AV sensor it performs all kinds or synthetic transactions, very similar to the transactions a regular user is performing. The sensor is using a test identity in your Teams environment and it uses a bot in Exoprise to communicate with. This way it can measure the call quality of Teams and it measure logon time, A/V streams (audio jitter, packet loss, bitrate), frames per second etc.

When configuring a sensor, an alarm is automatically created. This alarm can be configured during creation:

When the sensor is triggered because of a transaction, an alarm is sent to the email address that is configured and this gives you an immediate overview that something is wrong with the service. And to be honest, I was a bit surprised how often alarms are generated and thus how often you will receive an email. The email will show which sensor is generating the alarm, some analysis information and alarm details as shown in the following screenshot.

Besides the alarm message you’ll also get a weekly overview with real user performance data that is gathered from ‘the crowd’ so it averages over all Exoprise sensors that are deployed. This will show overall trends for all cloud services, for example:


There are multiple cloud monitoring solutions available and I had the opportunity to have a look at the ExoPrise solution. I was surprised by the ease of configuration and ease of use. It is a cloud based service, pull your credit card and you’ll be working within 20 minutes. It is a great tool for monitoring your environment, but at the same time it is a great tool for troubleshooting purposes (when you are a consultant).

I was also surprised by the data that was gathered by the ExoPrise sensors. It shows immediately when something is wrong, and you are notified before your users start calling the servicedesk that something is not working. And that happened more often than I thought before.


Microsoft UC Specialist