Back to blog

Office 365 Permissions Inventory: Calendar Permissions

Jul 25, 2017 by Vasil Michev

It’s time for the next article in our “Permissions Inventory” series. This time, we will take a look at Calendar permissions, more specifically the permissions on the default Calendar folder in users’ mailboxes. This kind of report is useful for keeping an eye on collaboration between your users (including external sharing), as well as troubleshooting delegate issues, and any issues with the default permissions levels.

Getting the permissions is a rather trivial task, as all you have to do is to run the Get-MailboxFolderPermission cmdlet. When you run this cmdlet against hundreds or thousands of mailboxes though, handling the output can get a bit tricky, especially when you have to account for aspects like the folder name localization in Exchange. Here’s a quick example:

As you can see from the above output, if you try to use the default “Calendar” name, the cmdlet will fail. Now, if you have run into this issue previously, you are probably aware that the folder might simply be renamed to match the language selected by the user, in this case German. One way to get around this issue is to hardcode all the known values for the name of the Calendar folder in different languages supported by Exchange Online, but this can get ugly, and time-consuming.

Instead, you could use the Get-MailboxFolderStatistics cmdlet to get the correct folder. Unfortunately, this means running yet another cmdlet for every mailbox you are interested in reporting on, thus increasing the overall script run time. We can speed things up a bit by reducing the output of the Get-MailboxFolderStatistics by using a combination of server-side and client-side filters, as shown below:

So far so good. However, we need to transform the Identity value in order to make sure the “:” symbol is added to it, and also handle any folder names that have the “/” character in their name. This isn’t a hard task, but something you need to keep in mind when dealing with folder level permissions.

Once all this is done, you need to take care of the actual output. As seen from the first screenshot above, multiple entries will be returned for each user, including the Default and Anonymous levels. In general, you might not be interested in these entries, but they can be useful in troubleshooting the “why can’t I see availability info for user XXX” type of issues, or the opposite: “how come user XXX can see my Calendar” complaints.

Apart from that, there are three kinds of permissions entries we will be looking into. First, we will of course cover internal sharing scenarios, where user X has granted permissions to user Y. Similarly, if sharing externally is allowed for the organization, we would also be interested in reporting on those instances. Finally, reporting on the “orphaned” entries might be useful in some cases, for example entries where the corresponding user Y is no longer a valid recipient (left the company, doesn’t have a mailbox anymore, etc).

And once we have gathered all these permission entries, we need to decide what to do with the output. One way to handle it is to write each permission entry on a new line in the CSV file, which creates a similar looking output to the Get-MailboxFolderPermission cmdlet. Of course, this will result in multiple entries per user/mailbox, but it does make it easier to filter. Another type of output can be generated by cramming everything into a single line per mailbox, thus reducing the number of entries. While the exact same information is achieved with both options, working with the output will be a bit trickier and you will have to use advanced filters or the “text to columns” functionality in Excel.

The actual script can be found on the TechNet Gallery:

Similar to the other scripts in the series, we make use of the PowerShell splatting concept to pass parameters when invoking the script. The first set of parameters controls which types of mailboxes will be included in the output, the default being only User mailboxes (used when you run the script without parameters or provide the –IncludeUserMailboxes parameter). Other supported types include Shared mailboxes as well as Room/Equipment mailboxes (-IncludeSharedMailboxes and –IncludeRoomMailboxes respectively). If you want to include all supported mailbox types, use the –IncludeAll parameter.
While technically we can also report on Group mailboxes, there is no method at present that actually allows you to grant folder level permissions to a Group (Calendar) folder, therefore only the default entries will be returned. Feel free to edit the script, and add Groups support if you wish, just remember to make use of the –GroupMailbox switch when running the Get-MailboxFolderPermission cmdlet. Similarly, Team and Discovery mailboxes are not included in the report.

Apart from the switches that control which mailbox types to include, one additional switch is made available to control the output type, namely the –CondensedOutput switch. Using it will return the “one line per mailbox” style of output, as detailed above. If you don’t specify the switch, the default one line per permission entry will be used instead. Feel free to let us know which type of output you prefer by commenting on this post.

As with other scripts in the series, no “connect to Exchange Online” code is included, only a simple check for an existing session. While care is taken to make sure the script runs as smoothly as possible, running it against large number of objects can result in getting throttled or broken PowerShell sessions. You can uncomment line 71 to add some delay between the cmdlets, and lines 115 and 140 to make sure the output is written to a CSV file after each iteration. If you don’t want to include the default permissions entries in the output, remove the comment mark from line 82.

And that covers everything you need to use this Calendar permissions script. For our next challenge, we will cover the permissions for all mailbox folders, not just the Calendar. Make sure you check back on the blog for the next instalment.