Script to generate report of Send on behalf of permissions in Microsoft 365

After a short break, I’m back to the “update PowerShell scripts” grind. This time we’re tackling a simple one – script to generate a report of all Send on behalf of permissions within the organization. You can find the original one here.

There’s nothing new when it comes to gathering inventory of Send on behalf of permissions in Microsoft 365. As before, we enumerate all mailboxes and group objects within the organization that have the corresponding GrantSendOnBehalfTo configured. In fact, we cannot even take advantage of the REST-based cmdlets, as unfortunately they do not support server-side filters for this particular scenario. So, we are still using the Get-Mailbox, Get-UnifiedGroup and Get-DistributionGroup cmdlets, however you will still notice improvements in the script execution time thanks to the changes made in the V3 module.

The connectivity block is changed to now leverage the Connect-ExchangeOnline cmdlet. If an existing session is detected, the script will try to reuse it (even if it’s an RPS one), else it will try to establish a new one. In that scenario, we further try to minimize the impact of the script by only loading the necessary cmdlets.

After connectivity is established, we continue with gathering the Send on behalf of permissions inventory. If you run the script without any parameters, it will generate a report covering all mailboxes (user, shared, room, equipment, scheduling, discovery and team mailboxes, to be more precise), all Microsoft 365 Groups and all Distribution groups (including mail-enabled security groups and Dynamic distribution groups). If you want to go more granular, you can mix and match between the following recipient types, each exposed as a separate script parameter:

  • IncludeUserMailboxes – use this parameter to include User mailboxes in the script output.
  • IncludeSharedMailboxes – use this parameter to include Shared mailboxes in the script output.
  • IncludeRoomMailboxes – use this parameter to include Room, Equipment and Scheduling (Booking) mailboxes in the script output.
  • IncludeGroupMailboxes – use this parameter to include Microsoft 365 Groups in the script output.
  • IncludeDGs – use this parameter to include Distribution Groups, Mail-enabled security groups and Dynamic distribution groups in the output.
  • IncludeAll – use this parameter to include all supported recipient types. This is the default behavior of the script.

Depending on the parameters used, the script will then proceed to run the Get-Mailbox, Get-UnifiedGroup and/or Get-DistributionGroup cmdlets as necessary. For each of these, a server-side filter against the GrantSendOnBehalfTo property is being used, as follows:

Get-Mailbox -ResultSize Unlimited -Filter {GrantSendOnBehalfTo -ne $null}

Some of you might wonder why we’re not using the Get-Recipient cmdlet instead, which will return all the supported recipient types in one go. And we can even use a server-side filter when doing so:

Get-Recipient -RecipientPreviewFilter {GrantSendOnBehalfTo -ne $null}

The reason is that the output of the cmdlet does not expose the actual property, so why we can tell which object have GrantSendOnBehalfTo configured, we cannot tell who the delegate is. And that’s probably something you want in the output of such a script. And while we’re on the topic of using other cmdlets, we cannot use the REST-based ones, as with them the server-side filter above will fail.

The rest of the script is handling the output. Nothing interesting here, just gathering the properties and arranging them a bit. Do note that the GrantSendOnBehalfTo property returns a string value representing the alias of the user – this might not be sufficient to uniquely identify them! However, figuring out the actual delegate object and replacing said property value with something more useful, such as the UserPrincipalName, is a task that will easily double the size of the script, and cause it to run a lot slower, so I’ve chosen the simple approach. As usual, feel free to modify the script to better suit your needs.

Output of the Send on behalf of scriptBefore closing the article, here is the link to download the script from my GitHub repo. And, some examples on how to run it:

#Runing the script without any parameters will generate a report of all supported object types

#The same will happen when you use the -IncludeAll switch
.\Mailbox_Permissions_inventory_SOB_V2.ps1 -IncludeAll

#To include only User mailboxes, use the -IncludeUserMailboxes switch
.\Mailbox_Permissions_inventory_SOB_V2.ps1 -IncludeUserMailboxes

Leave a Reply

Your email address will not be published. Required fields are marked *

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