In all fairness, a similar article can already be found on the blog. It was written by Alan back in 2012 and is accompanied by the Export mailbox permissions from Office 365 to CSV file script, one of the most downloaded scripts on the TechNet Gallery! Not an easy task to beat, and the intent of this article is not to compete with it, but give an updated and slightly different approach, while at the same time continuing or “Permissions Inventory” series.
Anyway, on to the task at hand. To get the mailbox permissions in Office 365, we have to connect to Exchange Online and use the Get-MailboxPermission cmdlet, which returns the following output:
The full list of users configured with any set of permissions to the mailbox in question will be displayed. In most cases however, this is just too much information. Yes, the Domain Admins in the Exchange Online forest will have permissions on your mailbox, but the same will be true for all other mailboxes. Thus, it makes sense to only limit the output to explicitly added permissions. A simple way to do so is to filter out any inherited permissions, by using the below example:
Now, the output is much cleaner, thus more useful. Alternatively, one can filter out all the individual Groups/accounts visible in the previous screenshot. The script attached to this blog post uses the first method.
In addition, the Get-MailboxPermission cmdlet might return orphaned entries, indicated by the presence of a SID value instead of the actual user. Excluding those is also possible. Lastly, one might want to limit the output to only entries that match exactly the FullAccess level of permissions. An example on how to get rid of all these entries is included in the script.
Now that we know how to get the mailbox permissions, let’s talk about the actual script. First of all, a script-based solution is needed since the Get-MailboxPermission cmdlet needs to be run individually against every mailbox you are interested in gathering the permissions for. In large organizations, this means looping against thousands of mailboxes, which will take considerable amount of time. To speed things a bit and minimize the resources used, the script uses the Invoke-Command method to gather the list of mailboxes and a small subset of their properties.
Further improvement in the speed of execution for the script is made possible by the fact that the output of the Get-MailboxPermission cmdlet now returns the UserPrincipalName attribute for user objects. Previously, only the display name was returned, which made it necessary to add additional checks (and thus additional cmdlets to execute) in order to make sure a unique identifier for the user is returned. An example on how to do this can be found in Alan’s script and although this part is no longer necessary for User objects, it can be used to uniquely identify Group-based permission entries (which still only return display name).
A progress indicator is included to make it easier to estimate the script completion time. As the script might still take considerable amount of time to execute, and output is only written to the console by default, you might consider removing the comment mark from the last line. In case the script fails often due to connectivity issues, an alternative approach is to uncomment line 95 so that output is written to a CSV file after each iteration.
Speaking of connectivity issues, the script does not handle connectivity to Exchange Online. As explained in the previous article, there are multiple ways to connect to ExO remote PowerShell nowadays, and most organizations have scripted their own solution. Connectivity is still checked for however, and if no active session is detected the script will fail. If you need help with connecting PowerShell to ExO, this article has all the needed information: https://technet.microsoft.com/en-us/library/jj984289(v=exchg.160).aspx
Similar to the Send on behalf of script, you can use the script parameters to specify the type(s) of mailbox(es) you are interested in, including User, Shared, Resource, Equipment, Team and Discovery mailboxes. Permissions for Group mailboxes are handled via “links” now, so they will be covered in a separate article. In the following example, we are using the script to gather permissions on all User mailboxes:
The output is stored by default in the $varPermissions variable, allowing you to immediately reuse it or modify it before exporting to CSV.
In summary, in this article we covered Full Access permissions in Office 365 and a refreshed script to gather their inventory. The script should be faster and more efficient, but the end result will be pretty much the same as with the original script found on the Cogmotive blog. A set of parameters is introduced to allow you to quickly filter different mailbox types. Alan’s script on the other hand allows you to feed the input objects from a CSV file, thus avoiding the need to loop over all mailboxes in the organization. In both cases, the assumption is that organizations will customize the script to better meet their needs, so please feel free to make any modifications and send us feedback!