Reporting Exchange Online Mailbox and SendAs/On Behalf Of Permissions

One Script to Report all Mailbox-Level Permissions

Shortly after publishing Reporting Exchange Online Mailbox Permissions, I received two notes. One was from Vasil Michev to say that I should have used the REST-based cmdlets from the Exchange Online Management module. The other was a reply to my note in the Microsoft Technical Community to point me to some script snippets covering “the other” mailbox-level permissions that you might assign over mailboxes. These are the Send As and the Send on Behalf Of permissions.

The snippets were just that: bits of code. These bits are valuable because the nature of PowerShell and the way the community works is that you can always (try to) improve what’s gone before. As it happens, I found much the same code in examples in my Exchange Inside Out 2010 book (still available from Amazon). In any case, the point was that knowing all about FullAccess permissions assigned to users is all very well, but to get a full perspective of the permissions set on mailboxes, you should include details of the sending permissions as well.

Three Exchange Online Cmdlets Needed

It would be nice if Exchange returned all mailbox permissions with a single cmdlet, but three are needed:

  • Get-ExoMailbox/Get-Mailbox: Returns a list of users with the right to Send as Behalf Of for a mailbox.
  • Get-ExoMailboxPermission/Get-MailboxPermission: Returns permissions granted on the mailbox, like FullAccess.
  • Get-ExoRecipientPermission/Get-RecipientPermission: Returns a list of users with SendAs permission for the mailbox.

The script uses the REST-based cmdlets but it’s easy to convert the calls to use the older Remote PowerShell cmdlets if you prefer.

The reasons why three cmdlets are needed are hidden in the mists of time and go back to the first implementation of PowerShell in Exchange 2007. The situation is unlikely to change now.

The Combined Script

The script is shown below. It’s a modified version of the previous script and you’ll need to connect to the Exchange Online Management module with an administrator account to run it. You can also download a copy from GitHub.

# ReportMailboxSendPermissionsMailboxes.PS1
# 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
# V1.0 16-Mar-2020
# https://github.com/12Knocksinna/Office365itpros/blob/master/ReportMailboxSendPermissionsMailboxes.PS1
CLS
Write-Host "Fetching mailboxes"
$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, SharedMailbox -ResultSize Unlimited -PropertySet Delivery -Properties RecipientTypeDetails, DisplayName | Select DisplayName, UserPrincipalName, RecipientTypeDetails, GrantSendOnBehalfTo
If ($Mbx.Count -eq 0) { Write-Error "No mailboxes found. Script exiting..." -ErrorAction Stop } 
CLS
$Report = [System.Collections.Generic.List[Object]]::new() # Create output file 
$ProgressDelta = 100/($Mbx.count); $PercentComplete = 0; $MbxNumber = 0
ForEach ($M in $Mbx) {
    $MbxNumber++
    $MbxStatus = $M.DisplayName + " ["+ $MbxNumber +"/" + $Mbx.Count + "]"
    Write-Progress -Activity "Checking permissions for mailbox" -Status $MbxStatus -PercentComplete $PercentComplete
    $PercentComplete += $ProgressDelta
    $Permissions = Get-ExoRecipientPermission -Identity $M.UserPrincipalName | ? {$_.Trustee -ne "NT AUTHORITY\SELF"}
    If ($Null -ne $Permissions) {
    # Grab information about SendAs 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.Trustee
           MailboxType = $M.RecipientTypeDetails } 
         $Report.Add($ReportLine) }}

    # Grab information about FullAccess permissions
    $Permissions = Get-ExoMailboxPermission -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) }} 

    # Check if this mailbox has granted Send on Behalf of permission to anyone
    If (![string]::IsNullOrEmpty($M.GrantSendOnBehalfTo)) {
       ForEach ($Permission in $M.GrantSendOnBehalfTo) {
       $ReportLine  = [PSCustomObject] @{
           Mailbox     = $M.DisplayName
           UPN         = $M.UserPrincipalName
           Permission  = "Send on Behalf Of"
           AssignedTo  = (Get-ExoRecipient -Identity $Permission).PrimarySmtpAddress
           MailboxType = $M.RecipientTypeDetails } 
         $Report.Add($ReportLine) }}
}

$Report | Sort -Property @{Expression = {$_.MailboxType}; Ascending= $False}, Mailbox | Export-CSV c:\temp\MailboxAccessPermissions.csv -NoTypeInformation
Write-Host "All done." $Mbx.Count "mailboxes scanned. Report of send permissions available in c:\temp\MailboxAccessPermissions.csv"

The output is a CSV file sorted by mailbox type (user mailboxes then shared mailboxes) and mailbox name. You can also pipe the output to Out-GridView (Figure 2) to quickly sort and review the results.

The full set of Exchange Online mailbox permissions
Figure 1: The full set of Exchange Online mailbox permissions

A Note About Get-ExoMailbox

The call to Get-ExoMailbox is a good example of how you need to pay attention to upgrading scripts from the older Get-Mailbox cmdlet. Get-ExoMailbox speeds access to data fetched from Exchange Online by forcing coders to specify the properties that they need to process. In this case, we need the Delivery property set (to access the GrantSendOnBehalfTo property) as well as the DisplayName and RecipientTypeDetails properties, which are specified individually.

As always, feel free to customize the script code to your heart’s content. Happy scripting!


Exchange Online is a well-known product at this point. Even so, a new development can throw up something that you don’t know about, just like the property sets used by the EXO cmdlets. Stay current by subscribing to the Office 365 for IT Pros eBook and let us do the heavy lifting of staying updated.

2 Replies to “Reporting Exchange Online Mailbox and SendAs/On Behalf Of Permissions”

Leave a Reply

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