When you perform a Public Folder migration from Exchange Server 2010 and newer to Office 365, a key step outlined in the Exchange Team Blog post Making your public folder migrations faster and more reliable is to ensure that you’ve performed clean-up prior to the migration.
If you don’t perform any clean-up of orphaned permissions or fix other issues with your Public Folder structure beforehand, then you will experience synchronization errors when you perform the migration itself. Therefore, it’s a good investment of your time to perform basic steps to check for and resolve these errors up-front.
Microsoft’s Source Side Validation script, described in the blog post above, will generate a log file showing amongst other things, orphaned ACLs you need to remove. However, it doesn’t go as far as to assist with the removal itself.
I’ve also found on Public Folder migrations that some issues do not get detected by the script. One in particular, which we will solve later on in this article, relates to AD user accounts that do not have the correct Exchange attributes assigned.
Despite the above, the Source Side Validation script will do a great job of providing a log file of issues you need to solve, and to help remove those orphaned permissions, I’ve created a script – RemovePermissionsFromSSV to use the log file as a input for permissions clean up.
In the example below, we’ll find issues using the Source Side Validation script, then use my script to remove the orphaned permissions.
First, we’ll run the SourceSideValidation.ps1 script:
The script will generate a log file, named in the format SourceSideValidations_<Date>_<Number>.log.
Open the log file to examine it:
Within the file we’ll see lines saying this folder <foldername> permission needs to be removed for NT User:<SID>.
These lines are showing an orphaned ACL. The orphaned ACL occurs when a user is deleted from Active Directory, but the permission is not removed from the Public Folder. This leaves just the security identifier (the SID) showing because it cannot be resolved to an actual user account.
This is a problem because when the folder is migrated to Office 365, the permission cannot be re-applied as the user doesn’t exist anymore.
The guidance on the Microsoft blog post doesn’t provide you much detail on how to use the log file to remove the permissions, and the guidance it does give doesn’t work on Exchange 2010. This is where the Remove-PFPermissionsFromSSV script comes in.
The script takes the lines from the log file, and for each line with a permission listed, it uses a command like the one below togGet the folder permissions, find the offending permission entry, and then remove it:
Get-PublicFolderClientPermission -Identity <Folder>| Where {$_.User -like <SID>} | Remove-PublicFolderClientPermission -Confirm:$False
Download the script from GitHub, and use it to first test what it can see to remove by using it in the following format:
.\Remove-PFPermissionsFromSSV.ps1 -SSVOutput <LogFile> -TestMode:$True
This will display output similar to that shown below, assuming no errors occur. The green lines indicate what it is attempting to test, and each line that follows shows the output from the Remove-PublicFolderClientPermission cmdlet with the -Whatif parameter:
If you are happy with the output (use Start-Transcript to capture it, if there are a lot of lines) then use the script again without the TestMode parameter:
.\Remove-PFPermissionsFromSSV.ps1 -SSVOutput <LogFile>
As above, I recommend using Start-Transcript before running the script to ensure you capture output. Running it without TestMode should provide cleaner, all green output showing each action:
After removing orphaned permissions, re-run Microsoft’s Source Side Validation script and examine the log file for errors. With any luck it should look like this:
The story would end here if Microsoft’s script was perfect, and unfortunately on a recent migration I encountered a scenario where it didn’t pick up all problem ACLs.
The scenario in question was one where my customer, after migration, was converting leaver’s mailboxes to shared mailboxes. Quite rightly they were following this support article from Microsoft which recommends setting the msExchRecipientTypeDetails to a particular value. The result of that corrupted the way the permissions are evaluated on the Public Folder permissions, so that they do not appear to be “ACLable” (assignable as permissions).
Upon further investigation, this also applies in another scenario – where you remove Exchange attributes from a Mailbox but keep the underlying Active Directory account (i.e. you run Disable-Mailbox). In that scenario the permission also shows in the same way and cannot be applied on the destination – nor can it be used by a user.
When this occurs the permission shows like this when examining it using Get-PublicFolderClientPermission or by using ExFolders:
As you can see in the above example, it is prefixed with NT User: and the account name, rather than resolving to a Mailbox, Remote Mailbox or other recipient.
To search for and then resolve this scenario, I’ve created a simple script called Remove-NTUSER.ps1, which you can download from my GitHub.
I’d recommend using the script, without parameters, to initially search for problem accounts after cleaning up permissions using the Microsoft Source Side Validation Script, otherwise it will show all other errors as well.
Firstly, use Start-Transcript to capture output, then run the Remove-NTUser.ps1 cmdlet with the Check parameter to only search for offending permissions:
.\Remove-NTUSER.ps1 -Check:$True
This should show, in green, potential folders and the users matching the NT User formatting:
For each line shown in the output, check the user account found, to see if it matches the scenarios described above.
If every permission found should be removed, then consider running a second time using the Remove and TestMode parameters to validate what will happen if the script attempts to remove the permissions:
.\Remove-NTUSER.ps1 -Remove:$True -TestMode:$True
The script should then run Remove-PublicFolderClientPermissions for each matching permission, using the WhatIf parameter to see what will occur:
Finally, if you are happy with the output above, run the script without the TestMode parameter to remove the permissions. After it completes, run the script again (either with the Check parameter or without – it defaults to check-only mode):
.\Remove-NTUSER.ps1 -Remove:$True -TestMode:$True
As shown below, it should remove offending permissions and display any errors as they occur. Re-running the script should show no output a second time:
Hopefully this article has been useful if you’ve been struggling with resolving issues with Public Folder migrations.
As the deadline for Exchange 2010 end of support approaches, I’ll follow up soon with a more detailed guide on getting your Public Folders migrated to Office 365 using up-to-date methods.
The script doesn’t create a log file.
Thanks for you post and scripts.
The NTUser removal one helped me out a lot with some hidden permissions which were not showing. they were indeed users who had been converted to shared mailboxes
Exchange Server 2016: I get the Error: The ampersand (&) character is not allowed, when trying to run the “Remove-PFPermissionsFromSSV.ps1″script.
I Run Exhange Powershell, as Administrator
Hi,
thank you for the sciprts but for me it doenst work… SSV generates the log-File and in run your “remove-…” skript. After this, SSV generates the same problems/permission issues 🙁
i run the skript in an elevated Exchange Shell and followed your instruction.
What can i do? Do you fixed the problem with spaces in public folder in your script?
Thanks Steve 🙂
This change will fix the problem with folders with space in their names:
…
$SSVLine=$SSVLine.Replace(“this folder “,””)
$SSVLine=$SSVLine.Replace(” permission needs to be removed for user “,”;”)
$Folder=($SSVLine.Split(“;”))[0]
$SID=($SSVLine.Split(“;”))[1]
…
Thanks, this worked perfectly!
Hi,
Thanks for the scripts.
Unfortunately the “Remove-NTUSER.ps1” script does not work if NT USER has “None” permission, orphaned permissions remain after running the script.
Thank you so much for this Steve. I’m currently working on a 2010 -> 2013 migration (on-prem). I ran through test system with all the scenarios I could think of. But didn’t think about orphaned accounts. This morning was looking through permission report on production side. Looks like a lot to cleanup there. Your scripts and information will be a big help.
Thank you again and take care,
Keith
Thank you Steve for the script! I use notepad or Excel to process the log file, use Replace function to delete “this folder ” from the log, then replace ” permission needs to be removed for user ” with a special character like “;”. Save the log and then open it with Excel, choose “;” as a delimiter, folder name and username are separated to 2 columns perfectly. Then save the file as csv or use it directly for scripting. I found Excel is a good tool for PowerShell. 🙂
do you have an updated script for public folders that have spaces in the name?
Apologies – I haven’t had a chance to update it yet – It is on my list!
how about bypass the script, and use the following
get-publicfolder “\” -recurse -resultsize unlimited | get-publicfolderclientpermission | where {$_.user -like “NT:S-1-5-21-xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-*”} | remove-publicfolderclientpermission -confirm:$false
Hey Steve, thanks very much. I’ve been battling with this exact issue for a number of months. I have a large number of orphaned SIDs, however when removing the permissions via PowerShell the orphaned SID remains.
I have contacted Microsoft, checked and repaired the databases via ESEUTIL etc but the issue remains. Any thoughts?
Have you had a different experience via PFDAVAdmin?
Hi Steve,
good script, it helped me a lot 🙂 , but the issue with the folders containing space it’s true, unfortunately i’m not a powershell expert and i don’t know how to fix it..
thank you for your howto and the script.
Ale
Thanks, I’ll take a look at the script and update it
Hi Steve,
I wanted to inform you about an issue with your script: if the public folder contains spaces, it wont work, because you split the path with ” “.
Thanks, I’ll take a look at the script and update it