How to Create a Report About Exchange Online Mailbox Permissions

Make Sure The Right People Access Your Exchange Online Mailboxes

One of the recommendations made in the Office 365 for IT Pros eBook is that tenant administrators should conduct periodic reviews of permissions assigned to mailboxes to ensure that the right people (other than the mailbox owners) have access. A recent request in the Microsoft Technical Community prompted me to look at the situation again to make sure that our advice was still accurate (it is).

Scripting a Report

I responded to the original question with some quick and dirty PowerShell but decided that a better job could be done. If you use the Get-MailboxPermission cmdlet to examine permissions on an Exchange Online mailbox, several types exist:

  • The mailbox owner (if you’re unsure, run Get-MailboxPermission with the -Owner parameter to see this entry).
  • Permissions needed by Exchange Online to access the mailbox for different purposes, such as removing items during retention policy processing. These entries appear like EXOForest\Organization Management, where “EXOForest” is the name of the Exchange Online forest hosting the mailbox.
  • An entry for “JitUsers” (Just in time access) assigned to Microsoft support personnel when they need access to the mailbox.
  • System entries like NT AUTHORITY\System and NT AUTHORITY\NETWORK SERVICE.

For the purpose of this exercise we don’t care about these permissions because they exist on all mailboxes. What we’re looking for are delegated permissions used to grant non-owner accounts access to the mailbox. Vasil Michev, our esteemed technical editor, has a script in the TechNet Gallery to report non-standard permissions, but there’s always room for another PowerShell answer to a problem.

My script (the full version is available on GitHub) selects user and shared mailboxes (those most likely to have extra permissions). For each mailbox, we extract the permissions and look for those assigned to other Office 365 accounts. We store details of these permissions into a list that is written out to a CSV file after all mailboxes are processed. Here’s the basic code:

# Quick and simple script to generate a report of non-standard permissions applied to Exchange Online user and shared mailboxes
# Needs to be connected to Exchange Online PowerShell with an administrative account to run
Write-Host "Fetching mailboxes"
$Mbx = Get-Mailbox -RecipientTypeDetails UserMailbox, SharedMailbox -ResultSize Unlimited | Select DisplayName, UserPrincipalName, RecipientTypeDetails
If ($Mbx.Count -eq 0) { Write-Error "No mailboxes found. Script exiting..." -ErrorAction Stop } 
# We have some mailboxes, so we can process them...
$Report = [System.Collections.Generic.List[Object]]::new() # Create output file 
$ProgressDelta = 100/($Mbx.count); $PercentComplete = 0; $MbxNumber = 0
ForEach ($M in $Mbx) {
    $MbxStatus = $M.DisplayName + " ["+ $MbxNumber +"/" + $Mbx.Count + "]"
    Write-Progress -Activity "Processing mailbox" -Status $MbxStatus -PercentComplete $PercentComplete
    $PercentComplete += $ProgressDelta
    $Permissions = Get-MailboxPermission -Identity $M.UserPrincipalName | ? {$_.User -Like "*@*" }    
    If ($Null -ne $Permissions) {
       # Grab each permission and output it into the report
       ForEach ($Permission in $Permissions) {
         $ReportLine  = [PSCustomObject] @{
           Mailbox    = $M.DisplayName
           UPN        = $M.UserPrincipalName
           Permission = $Permission | Select -ExpandProperty AccessRights
           AssignedTo = $Permission.User
           MailboxType = $M.RecipientTypeDetails } 
         $Report.Add($ReportLine) }
$Report | Sort -Property @{Expression = {$_.MailboxType}; Ascending= $False}, Mailbox | Export-CSV c:\temp\MailboxPermissions.csv -NoTypeInformation
Write-Host "All done." $Mbx.Count "mailboxes scanned. Report of non-standard permissions available in c:\temp\MailboxPermissions.csv"

The CSV file is stored by user mailbox and then shared mailbox (you must use a calculated expression to sort by multiple properties when the first property is sorted in descending order).

Note: If you want to use the REST-based cmdlets in the Exchange Online Management module, replace Get-Mailbox with Get-ExoMailbox and Get-MailboxPermission with Get-ExoMailboxPermission in the script.

Reviewing the Results

As you can see from Figure 1, the resulting CSV reports a number of FullAccess permissions assigned to mailboxes. This isn’t an issue by itself because FullAccess permission is needed by delegates to have full control over a shared or user mailbox (as in the case of Outlook Mobile delegation). However, it’s important to review each assignment to understand if it is still valid and necessary. If not, the permission should be removed.

 Reporting mailbox permissions
Figure 1: Reporting mailbox permissions

This report doesn’t include folder-level permissions assigned by Outlook. These permissions can be reviewed with the Get-MailboxFolderPermission cmdlet. To find all such permissions for a mailbox, you would need to run Get-MailboxFolderStatistics to generate a list of mailbox folders and then check each folder to see if any permissions exist. I’ll cover how to do this in a future post.

For many more examples of using PowerShell to manage Exchange Online and other Office 365 components, subscribe to the Office 365 for IT Pros eBook and find some hidden jewels.

4 Replies to “How to Create a Report About Exchange Online Mailbox Permissions”

  1. Once you have the data, what’s a good process for getting it distributed to users then collecting their responses?

    1. That depends on your organization. One simple approach is to send email to the owner of each mailbox with permissions set to as them if the permissions are still required,.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.