Making your public folder migrations faster and more reliable

Published Oct 17 2019 06:59 AM 23.9K Views

The key for a successful migration (of any type) is to ensure that source data is in a healthy condition. Public folder migrations are no different, especially if you have been using public folders for years. Orphaned ACLs, mis-matched Mail Enabled Public Folder objects (MEPF’s), or corrupted dumpster folders can cause public folder migrations to slow down considerably, if not fail altogether.

We are happy to provide admins with a Source Validation script (clicking will start download of the script) which can scan and report on issues found with public folder deployments. The script can be used to scan legacy public folder deployments hosted on Exchange Server 2010 or modern public folder deployments on Exchange Server 2013, Exchange Server 2016 or Exchange Server 2019. It is recommended to use this script to scan public folder deployments before the start of a migration and fix any issues reported before proceeding with migration.

Currently, the script checks and reports:

  • Orphaned ACLs
  • Health of Mail Enabled Public Folder (MEPF) objects*
  • Health of Dumpster folders*
  • Check if the source fits in the current EXO limits.

*These tests are valid for public folder deployments on Exchange 2013 and above.

Script usage

Download the script from here, copy it to on-premises servers and execute from Exchange Management Shell. The script reads public folder hierarchy and stores the information into CSV files on the disk. Then, various checks are performed using the information stored in the CSV files. The results, along with actions to be performed, are presented in a log file named “SourceSideValidations.[yyyyMMdd_HHmm].log”

Important parameters:






Specifies if MEPF integrity check needs to performed. By default, set to true. The option works for Exchange Server 2013 and above.



Specifies if Limits need to be checked for public folder. By default, set to true.



Specifies if public folder mapping with dumpsters needs to be verified. By default, set to true. The option works for Exchange Server 2013 and above.



Specifies if permissions need to be checked on public folders. By default, set to true.



Specifies if the script should read from files on the disk or read from PF structure again. Default value is true. The script will read the PF structure and create log files on the disk. Specify startAfresh:$false in case the script execution was interrupted for any reason and needs to be resumed from the point where script was interrupted.


The following example shows how to perform only dumpster mapping check:


.\SourceSideValidations.ps1 -verifyMEPF $false -verifyDumpsterMapping $true -checkLimits $false -checkPermissions $false


The following example, without providing any parameters performs, all the checks (i.e. -MEPF, Limits, DumpsterMapping and Orphaned ACL check):




The following example shows how to have script read public folder information from the existing files. This is useful in scenario if the script execution was interrupted and needs to be resumes from the time of interruption:


.\SourceSideValidations.ps1 -startFresh:$false


Additionally, here are some important points to be noted:

  • Script execution time depends on the size of public folder deployment on-premises. For larger deployments, script may take several hours to complete.
  • The script must be executed from the appropriate source server within your on-premises deployment of public folders. For example, if you have public folders deployed on Exchange 2010 (legacy public folders), even if the environment also has Exchange 2013/2016 servers installed, the script must be executed from the Exchange 2010 server. But if your environment uses modern public folders, you would run this on an Exchange 2013/2016/2019 server.
  • The script reports issues into a log file, saved in the execution folder. The log file name looks like:



  • The script will also recommend actions to be performed to fix the issues, however, the script itself will not fix any found issues.

Please leave a comment to let us know your feedback about the script. Happy public folder migrations!

Public Folder Team

Occasional Visitor

If you want to run this on an Exchange 2010 environment, run it on a mailbox server. I experienced problems when running from both a management server and a CAS.

Senior Member

This script has helped identify several issues so far, however it is returning a number of entries like this one:
EntryId 000000001A447390AA6611CD9BC800AA002FC45A03003C79FE3DD4892149875958C8A1A9CD2A0000000001C50000.EntryId does not have a corresponding dumpster folder

Any idea how to track this issue down?

Occasional Visitor

Very nice script, and happy to see that you this time, take measurements for enviroments, where the script cannot complete within the 10 hours that the PowerShell session is valid, for large enviroments :)


When that is said, i do see an issue with this script, as it does not take into account, for enviroments where the MESO objects also is place under a child/root domain. Please include the line below in the script:


Set-ADServerSettings -ViewEntireForest $true



Senior Member

What about the check if a Mail Publicfolder belongs to a member of a distribution group? This is also a scenarios that causes problems.

New Contributor

Thanks, though for the ACL portion, I'd suggest an option to automatically backup and remove the permissions, or at least include the AccessRights in the log file. Presently the log states the folder name and user with an ACE error, but Remove-PublicFolderClientPermission requires the name of the AccessRight itself, so we're not able to feed the log file back into a "fix script" without looking up the whole ACL again.

Occasional Visitor

When I run this script I get multiple errors like:

this folder \***** ****\******_***_** permission needs to be removed for user NT User:S-1-5-21-**********-**********-**********-****

How can I automate removing the user? 

I thought about

Remove-PublicFolderClientPermission -identity "\***** ******" -User "S-1-5-21-**********-**********-**********-****" -Confirm:False

but can't do so, because Remove-PublicFolderClientPermission needs a real (principal) User Name not a guid.

Thanks in advance

Senior Member

@DiSmo  edit your "SourceSideValidations" file like


"\folder\folder1\folder3","User Name"



$get_folder_user = Import-Csv .\edited_SourceSideValidations.csv
foreach($object in $get_folder_user) {Remove-PublicFolderClientPermission -Identity $object.folder -User $object.user -Confirm:$false}

hope it helps


Occasional Visitor
I've been running this script now for 48 hrs. Is that normal? Should I end this? It just keeps going thru the list of folders over and over.


Please advise

Occasional Contributor

what are the exact limits on migrating onprem PFs to o365 EXO?  i think your documentation team are confusing issues as they've said 100 folders.

Senior Member

The script is a good idea, but the output is unusable. It requires significant work to transfer the text file output to a CSV file. Furthermore, in order to remove permissions, you need the principal and access rights, so I ended up querying again just before removing. 

Regular Visitor

I have tons of errors like this:

folder name ... has an invalid dumpster which is 000000001A447390AA6611CD9BC800AA002FC45A0300FEE8624D3302BF41BC3DC428610D460500062D5D62AA0000
14867 folders have issue with dumpsters


I got Exchange 2013, so I can't use -CreateAssociatedDumpster.


Any idea?

Senior Member

@Tino JR just open the file in Excel then create your own delimiters to get a column for the folder and a column for the user.

Occasional Visitor

I'm getting the below error when I'm running the script. I got Exchange2010.

Any advice appreciated.


Add : You cannot call a method on a null-valued expression.
At C:\PFScripts\SourceSideValidations.ps1:246 char:27
+ $errorList.Add <<<< ("this folder " + $ipmFolder.Identity + " permission needs to be removed for user " + $perm.User) > $null
+ CategoryInfo : InvalidOperation: (Add:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull


Add : You cannot call a method on a null-valued expression.
At C:\PFScripts\SourceSideValidations.ps1:483 char:16
+ $errorList.Add <<<< ("Found no errors... ") > $null
+ CategoryInfo : InvalidOperation: (Add:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull


New Contributor

[PS] C:\Users\administrator\Downloads>.\SourceSideValidations.ps1 -verbose
Couldn't find an available public folder database. Make sure that there is a public folder database on at least one server that has the Mailbox server role installed, and that
the public folder database is mounted.
+ CategoryInfo : NotSpecified: (:) [], TaskInvalidOperationException
+ FullyQualifiedErrorId : 676FE8F7
+ PSComputerName :


EX2010 SP3 UR22


Edit: Database needed eseutil.

New Contributor

To give others with a bigger public folder environment an idea of how long the SourceSideValidations.ps1 script can take, in my case it ran for almost 5 full days before finishing and producing the "SourceSideValidations.<date>.log" file. Seems like a poorly written script as the output is not friendly for converting into a CSV that you could then use to take action on the findings more easily. In my case there was just under 68k folders that needed permission changes. An example of a log entry was: "this folder \<Folder Name> permission needs to be removed for user NT User:S-*-*-**-*********-**********-**********-*****". If you look in the script you could edit the function "function checkACL($ipmFolder)" and change the output to something like this: "$errorList.Add("this folder," + $ipmFolder.Identity + ",permission needs to be removed for user," + $perm.User.DisplayName) > $null". The commas would allow you to break up the log in Excel using Text to Columns - Delimited with the comma as the delimiter. In the log it included a line of how the permission errors could be resolved (Remove-PublicFolderClientPermission <folder identity> -User <username> -Confirm:False) but in my case since it was a NT User:-S* account that represented a user or group that no longer was in our Active Directory that did not work for me. Instead I just used the script found here to roll through all public folders and remove the unresolved SIDs.

Occasional Visitor

I"m about to migrate Public Folders from Ex2013 to EXO, I got this error for all mail enabled "This EntryID is present in AD but not in Exchange" (which doesn't make sense), how can I manually verify one in order to better understand why we getting this error for all?

Occasional Contributor

@ryaron  I have the same issue but the Entry Id is not showntempsnip.jpg

Version history
Last update:
‎Oct 17 2019 07:03 AM
Updated by: