Folder Permissions - Backup and Restore
I ran into a problem where I needed to be able to backup and then restore permissions to some mailboxes. While this looks like it should be a straightforward thing to do, it turned out to be more complicated than I first though. I'll give you a word of warning on this right up front - this takes about one second per folder to gather permissions! If you think you're going to do a backup of 1000 mailboxes like this, with 50 folders per mailbox, well that's going to be something like 14 hours to run. Restores take even longer.
Here's the script I use for doing backups on mailbox folder permissions:
#Save-FolderPermissions.ps1 - grb - 12/17/2014 - This script takes the user and gets folder permissions for the user, exporting it a CSV file.
#variable setup
#You can save only the permissions for the inbox and subfolders with '/Inbox*', for example.
$StartFolder = '/*'
$SaveDir = 'c:\temp\'
$MailboxCount = 0
#Import CSV of all the SMTP address of each of the mailboxes to get its permissions saved
$Mailboxes = Import-Csv -Path ($savedir+"_FolderPermissionsMailboxes.csv")
Foreach ($Mailbox in $Mailboxes) {
#Define $Permissions as an array
$Permissions=@()
#We are going to get a running count of the mailboxes that we are doing. This can be a slow process, so we'll want a status.
$MailboxCount += 1
echo '======================='
echo ('Gathering Statistics for: '+$mailbox.SMTP)
echo ('Mailbox '+$MailboxCount+ ' of '+$mailboxes.Count+' mailboxes')
#Get the folders for the mailbox
$folders = Get-MailboxFolderStatistics -Identity $mailbox.SMTP | ? {$_.FolderPath -like $startfolder} | Select FolderPath
Foreach ($folder in $folders) {
$FolderID = $mailbox.SMTP+":"+($folder.FolderPath | Foreach-Object {$_ -replace "/", "\"})
$Permission = Get-MailboxFolderPermission $FolderID -ErrorAction SilentlyContinue | Select Identity,user,AccessRights,IsValid
$Permissions += $Permission
}
$Permissions | Export-Csv -Path ($savedir+$mailbox.SMTP+"-FolderPermissions.csv") -NoTypeInformation
}
echo "Completed"
#done
You might be wondering about this line:
$FolderID = $mailbox.SMTP+":"+($folder.FolderPath | Foreach-Object {$_ -replace "/", "\"})
It would be nice if the Get-MailboxStatistics command output the folder in the same format that Get-MailboxFolderPermission used. Yeah, not so much. The above fine fixes the formatting between the two commands.
Remember, also, that we needed a CSV file, right? Heres's what that CSV file look like. It's just SMTP addresses of the mailboxes to be backed up, plus the header.
SMTP
User1@contoso.com
User2@contoso.com
Now we have to be able to do a restore. I have a script for that, too.
#Restore-FolderPermissions.ps1 - grb - 12/22/2014 - This script takes the user and imports folder permissions from a CSV file, restoring them.
#variable setup
$SaveDir = 'c:\temp\'
$MailboxCount = 0
#Import CSV of all the SMTP address of each of the mailboxes to get its permissions restored
$Mailboxes = Import-Csv -Path ($savedir+"_FolderPermissionsMailboxes.csv")
Foreach ($Mailbox in $Mailboxes) {
#Define $Permissions as an array
$Permissions=@()
#We are going to get a running count of the mailboxes that we are doing. This can be a slow process, so we'll want a status.
$MailboxCount += 1
echo '======================='
echo ('Restoring Permissions for: '+$mailbox.SMTP)
echo ('Mailbox '+$MailboxCount+ ' of '+$mailboxes.Count+' mailboxes')
$Permissions = Import-Csv -Path ($savedir+$mailbox.SMTP+"-FolderPermissions.csv")
Foreach ($Permission in $Permissions) {
Set-MailboxFolderPermission $Permission.Identity -AccessRights $Permission.AccessRights -User $Permission.User -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
Add-MailboxFolderPermission $Permission.Identity -AccessRights $Permission.AccessRights -User $Permission.User -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
}
}
echo "Completed"
#done
Why use both the "set" and "add" for the folder permissions? One of the commands will modify permissions and the other adds them if they are removed. Either might be needed, so we try both and just ignore the errors.