Deleting rogue mailbox folder permissions using PowerShell

Yesterday, I wrote a little post about analyzing your hybrid migration logs, using PowerShell. In the case I showed in that post, the large number of BadItems that were causing my move to fail, turned out to be caused by rogue permissions on mailbox folders in the users mailbox. These permissions were given to users that no longer exist in the directory, so they can not be moved to Exchange Online, causing the move to fail.

So, How do we remove these permissions? Well, with PowerShell ofcourse 😉 I wrote up a quick script that checks for rogue permissions on a given mailbox and then removes them. The script is tested only in my environment, so if you want to use or adopt it, please be careful.

First, we need to get a list of al folders in a mailbox so we can check the permissions for those folders. Unfortunately, get-mailboxfolder only works if your querying a mailbox that your the owner of. You can’t use this cmdlet as an administrator to check other people’s mailbox. But, we can use get-mailboxfolderstatistics as a workaround. We just need to make sure we only select the output we need.

get-mailboxfolderstatistics MailboxAlias | select-object FolderPath

This gives us a list of folder that are in the given mailbox. We can then use this list to check al those folders for any rogue permissions. If you investigate the permissions on a mailbox folder, you’ll see that the ‘User’ attribute for these rogue permissions will be the user SID, in stead of the username. As al SID’s start with ‘NT:’, we can use this to filter out the rogue permissions.

get-mailboxfolderpermission 'Username:\Inbox\Subfolder' | where {$_.user -like 'NT:*'}

We now have a list of folders and the corresponding invalid permissions. It’s fairly easy to delete those with the remove-mailboxfolderpermission cmdlet.

remove-mailboxfolderpermission -identity 'Username:\Inbox\Subfolder' -user 'RogueUserSID'

So now for the cool part: putting all those puzzle pieces together to create one script. It’s fairly simple, using two foreach-loops: one to loop through all the folders for a mailbox to get the incorrect permissions, and another one to loop through all the rogue permissions to actually remove them.

The nasty part is in creating a correct list of folders to query the permissions. The list of folders form the get-mailboxfolderstatistics cmdlet contains only folder names, using a forward slash (/) to separate the folders, while the get-mailboxfolderpermission cmdlet expects the folder path to use backslashes (), and include the name of the mailbox followed by a colon symbol (:). To work around this, I build a $folderpath variable combining the alias, a colon symbol and the folder path from get-mailboxfolderstatistics, combined with the -replace parameter to replace all forward slashes with a backslash.

To top it all off, I do some filtering in the get-mailboxfolderstatistics cmdlet to exclude some folders. These are folders (like ‘top of information store’) that will generate an error if you try to query the permissions.

The entire script then ends up looking like this:

$alias = "365Dude"
$folders = get-mailboxfolderstatistics $alias | where {($_.foldertype -ne 'Root') -and ($_.foldertype -notlike 'Recoverable*') -and ($_.foldertype -ne 'CalendarLogging')} | select-object FolderPath
foreach ($folder in $folders) {
    $folderpath = $alias + ":" + $folder.folderpath -replace "\/", "\"
    $rogues = get-mailboxfolderpermission $folderpath | where {$_.user -like 'NT:*'} -ErrorAction SilentlyContinue
    foreach ($rogue in $rogues) {
        $user = $rogue.user.displayname
        write-output "Removing $user from $folderpath"
        Remove-MailboxFolderPermission -Identity $folderpath -User $rogue.user.displayname -Confirm:$false -whatif

Of course, if you like to run this in your own environment, be careful and make sure to know what your doing. If you are really, really sure it will be okay, remove the -whatif parameter from the last line and have fun.

Happy scripting!