February 27, 2014

How To Use PowerShell To Connect To Office 365 And Recursively Add Mailbox Folder Permissions

In case you haven’t noticed, Microsoft is making you do more and more with PowerShell. Features we’d love to see in a GUI interface instead require commands and scripts. Okay, this is good when you want to automate things, but not so great for the occasional need. For example, where I work we occasionally need to grant one user access to folders in another user’s exchange mailbox. And in our environment, our exchange is in the cloud, or in other words, we use O365 (Office 365). Microsoft doesn’t offer us a great way to do this via GUI unless we want to take control of an actual mailbox account (or walk a user through it over the phone). So even for these rare occurrences, and for things that don’t need to be automated, we still need to head to the PowerShell command prompt to get the job done. To grant mailbox and folder permissions via PowerShell, here’s what you need to do:

1. First you need to make sure you have the correct version of PowerShell and WinRM, and Microsoft has already done the work in writing that article: Install and Configure Windows PowerShell Enable and Use Remote Commands in Windows PowerShell

2. Next you need to make sure that the account you use to login to O365 via PowerShell is authorized to connect to WinRM (by default you should be able to): Control Users’ Access to Windows Remote Management

3. Now you need to connect Windows PowerShell to O365. Microsoft also has an article for that (“Connect Windows PowerShell to the Service“) but I will also list the procedure in the following steps.

4. Start Windows PowerShell and once the prompt appears, run this command:

$LiveCred = Get-Credential

5. A GUI login prompt will appear. Login with your fully qualified domain credentials (example: username@xyz.corp.com)

6. Now run this command to initiate the connection:

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection

7. To import cloud-based commands to your local computer, run this command:

Import-PSSession $Session

Note: If you get an error saying “Import-PSSession : Files cannot be loaded because running scripts is disabled on this system” you can remedy this by running this command (then running the Import-PSSession command again):

set-executionpolicy unrestricted

8. Now you are ready to grant those permissions. If you simply need to give someone “full access” to another person’s mailbox, you can run this command (where “sharer” is the person who is sharing their account and “sharee” is the person connecting to the shared account):

Add-MailboxPermission -Identity sharer@xyz.corp.com -User sharee@xyz.corp.com -AccessRights FullAccess -InheritanceType All

You can find all the “-AccessRights” and more examples and info here: Add-MailboxPermission (Exchange Server 2013)

9. If you want to add individual mailbox folder permissions, run this command:

Add-MailboxFolderPermission sharer@xyz.corp.com:\Invoices -User sharee@xyz.corp.com -AccessRights Owner

You can find all the “-AccessRights” and more examples and info here: Add-MailboxFolderPermission (Exchange Server 2013)

If you find that a permission has already been assigned, you can use the “Set-MailboxFolderPermission” command instead. This command will “set” a new permission if a previous permission already exists for the specified user.

10. Now here’s where the real fun begins. If you want to recursively add folder permissions to all sub-folders in a mailbox, run this (script) command:

ForEach($f in (Get-MailboxFolderStatistics sharer@xyz.corp.com | Where { $_.FolderPath.Contains("/") -eq $True } ) )
$fname = "sharer@xyz.corp.com:" + $f.FolderPath.Replace("/","\"); Add-MailboxFolderPermission $fname -User sharee@xyz.corp.com -AccessRights Owner
Write-Host $fname
Start-Sleep -Milliseconds 1000

Similar to step 9, when you run the above script and you notice one or more errors that a previous permission already exists, you can run the script again, this time replacing “Add-MailboxFolderPermission” with “Set-MailboxFolderPermission” and it will “set” the new permission everywhere it finds a previous (but different) permission for the user specified.

Note: The “Start-Sleep” command is for rate limit avoidance. Microsoft throttles your PowerShell connection to O365 and will only allow you to run approximately one command per second. If you run the above script without the “Start-Sleep” command, and there are a lot of folders to process, you will start to see throttle messages in your PowerShell console. The reason you want to self-impose a wait time, is that Microsoft starts to severely throttle your connection the more commands that are processed. So it’s best to start from the beginning with a Start-Sleep setting that avoids server-side throttling.

11. If you want to recursively add folder permissions to just one sub-folder branch in a mailbox, run this (script) command (note the change from the above script in the “FolderPath.Contains” section):

ForEach($f in (Get-MailboxFolderStatistics sharer@xyz.corp.com | Where { $_.FolderPath.Contains("/Invoices") -eq $True } ) )
$fname = "sharer@xyz.corp.com:" + $f.FolderPath.Replace("/","\"); Add-MailboxFolderPermission $fname -User sharee@xyz.corp.com -AccessRights Owner
Write-Host $fname
Start-Sleep -Milliseconds 1000

12. You can also go in reverse. To remove folder permissions recursively, run this (script) command:

ForEach($f in (Get-MailboxFolderStatistics sharer@xyz.corp.com | Where { $_.FolderPath.Contains("/") -eq $True } ) )
$fname = "sharer@xyz.corp.com:" + $f.FolderPath.Replace("/","\"); Remove-MailboxFolderPermission $fname -User sharee@xyz.corp.com -Confirm:$False
Write-Host $fname
Start-Sleep -Milliseconds 1000

13. To end your PowerShell session to O365, run this command:

Remove-PSSession $Session

Please share your thoughts