Table of Contents
It’s All About Permissions for the Default User
Tracking the availability of other people in your organization has been a problem for calendar management systems since the early 1980s. Microsoft’s solution since the days of Schedule+ has been to publish free and busy information from user calendars to allow other people to see if someone is available when setting up a meeting. The information is presented in time slots by apps like Outlook’s scheduling assistant (Figure 1). Good as it is to see time slots, it’s limited access to view calendar information.

As you can see from Figure 1, more insight is available about the availability of some people than others. The ability to view details of someone’s availability depends on the permission you have to their calendar (private items like the one shown are exceptions to the rule).
Default Permission for the Default User
The default permission used within Exchange Online is AvailabilityOnly. This is one of two special permissions available for the calendar folder and it allows other users to see a graphic representation of when someone is available. However, this permission doesn’t allow you to see details of what you’re up to like the Procurement call highlighted in Figure 1. The ability to see this information is governed by the other special permission (LimitedDetails), which allows people to see the time slot reserved, the title, location, and its time status (busy, tentative, out of office, etc.).
To make sure that everyone within an organization has at least limited visibility of each other’s calendar, Exchange Online assigns the AvailabilityOnly permission to a special user called Default. People see this assignment in a slightly different manner because clients present the information in a more user-friendly manner. For instance, OWA refers to the Default user as People in my organization and interprets the permission as Can view when I’m busy (Figure 2).

Figure 2 also shows that individuals can assign specific permissions to different users to allow them to have custom access to a calendar. This is what happens when people need to manage the calendar for other users.
Using PowerShell to Set a New Default Permission
You’re all set and there’s no more to do if you’re happy with everyone seeing calendar slots instead of appointment details. Things become more complicated if you decide that it would be better if everyone could see more information. There will always be exceptions where you want to protect calendars against casual browsing (“I wonder what the CEO is doing today…”), but the idea is to allow general access as a default.
It sounds like this is something that should be handled by a setting in Exchange’s organization configuration to control the default permission created for new calendars. Unhappily, no such setting exists, and anyway, if it did, you’d still have the problem of retrofitting a new default permission on existing calendars, including the need to respect customized permissions set for some calendars.
Which brings us to PowerShell. The Set-MailboxFolderPermission cmdlet in the Exchange Online management module is the key to assigning a new default permission to existing mailboxes and for subsequently-created mailboxes. To set a new default calendar permission, we need a script to:
- Use a method to indicate if a mailbox has already been updated or should be ignored because it has custom permissions.
- Find target mailboxes.
- Run Set-MailboxFolderPermission against each mailbox.
- Update the mailboxes so that they are not processed the next time the script runs.
Custom mailbox attributes are a good choice for storing an indication that a mailbox has updated permissions. It’s easier and faster to check a custom attribute because these attributes support server-side filtering and don’t need to check the actual permissions in place on mailboxes. With that in mind, I elected to use CustomAttribute13 to store “Open” if the mailbox is updated with a new default permission and “Blocked” if a mailbox is to be ignored.
An admin (or the user if they know how to run Set-Mailbox in PowerShell) would set the attribute to Blocked if they don’t want their availability setting updated. You’d probably have a set of well-known mailboxes to block and would process them at one time. For instance, let’s assume you have a CSV file containing the user principal names of mailboxes to block. The code would be something like:
$Mbx = Import-CSV c:\Temp\SomeTempFile.csv ForEach ($M in $Mbx) { Set-Mailbox -Identity $M.UserPrincipalName-CustomAttribute13 "Blocked"}
The prototype code to find and update the availability setting for mailboxes (I’ve opted to process user and room mailboxes) with the new default calendar permission is shown below. You’ll note that I have some lines to deal with local language values of the name for the calendar folder. You will have to uncomment and use this line (it’s reasonably expensive to run Get-ExoMailboxFolderStatistics to find the calendar folder and extract its name) if your organization includes users who run Outlook or OWA in non-English languages. Some experimentation is required!
# Find mailboxes that we have not yet reset the default sharing view [array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, RoomMailbox -ResultSize Unlimited -Filter {CustomAttribute13 -ne "Open" -and CustomAttribute13 -ne "Blocked"} $CalendarName = "Calendar" # English language calendar folder ForEach ($M in $Mbx) { Write-Host "Processing" $M.DisplayName # You can hard-code the calendar name (above) or try and find a local language value. This is one way to look for local values... # $CalendarName = (Get-ExoMailboxFolderStatistics -Identity $M.UserPrincipalName -FolderScope Calendar |?{$_.FolderType -eq "Calendar"}).Name # Either way, you need to end up with a valid calendar folder reference - like Tony.Redmond@office365itpros.com:\Calendar $CalendarFolder = $M.UserPrincipalName + ":\" + $CalendarName Set-MailboxFolderPermission -Identity $CalendarFolder -User Default -AccessRights LimitedDetails Set-Mailbox -Identity $M.ExternalDirectoryObjectId -CustomAttribute13 "Open" }
The first time you run the script, it will take plenty of time to process mailboxes (expect each mailbox to take between 2-3 seconds to be updated). Later, fewer mailboxes will need updating and the script will complete faster. To be sure that new mailboxes get the new default permission, you can run the script periodically, perhaps as a scheduled task or using Azure Automation.
Figure 3 shows the effect of the change. Availability information is visible for all participants.

The updated access to free and busy information will be picked up by any client which consumes this data, such as the scheduling assistant in the Teams calendar app (Figure 4).

Need for Calendar Option in Mailbox Plan
You can argue that Microsoft should make it easier for organizations to select and apply a default calendar permission. However, you’d still probably have to run some PowerShell to adjust the permission for selected mailboxes, like those who need to preserve confidentiality. Still, it would be nice if Microsoft added the default calendar permission to mailbox plans so that new mailboxes would receive whatever permission deemed suitable by an organization. That would be a good step forward.
Learn more about how Office 365 really works on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.
Hello Tony!
Great article (as always)!
I’d add two things to the above:
1) For those of us that work in the mutinational (or non-english) environments, when end user mailbox locale can be anything, calendar folder name doesn’t have to be ‘Calendar’. To work around that i’ts possible to retrieve the folders of calendar type using
$calendarFolderName=(get-exomailboxfolderstatistics -Identity $m.alias | ? {$_.foldertype -eq ‘Calendar’}).name
and then use this $calendarFolderName variable.
So instead
$CalendarFolder = $M.Alias + “:\Calendar”
we would have sth like
$CalendarFolder = “$($M.Alias):\$($calendarfoldername)”
2) Despite the default (system) calendar, user can also create custom folders of calendar type. Unfortunately, the ‘foldertype’ of such user-created calendars is not ‘Calendar’. It is ‘User Created’ (as any other folder created by user in mailbox). If there was a need to deal with all calendar-type folders (including user created), the cmdlet should be
$calendarFoldersNames=(get-exomailboxfolderstatistics -Identity $m.alias | ? {$_.containerClass -eq ‘IPF.Appointment’}).name
Then this variable should be treated as an array and put into loop accordingly.
I hope this adds some value to the above.
Thanks for reminding me that English is not the b-all and end-all of IT. You’re 100% right to use a language dependent version of the calendar folder name. I made some changes to the code you suggested (using the FolderScope is faster as it avoids the need to process all folders in the mailbox). See what you think.
Hi Tony, thanks for script. Any assistance with this would be greatly appreciated.
This is exactly what I need, but with one issue. I need it in an AAD Synced tenant.
– I am accessing it from a delegated admin tenant.
– users are syncing from on premise
– Microsoft Business Premium licenses with password write back ability
Issue:
I cant figure out a way to apply the -customattribute to an on premise AD object while its processing the permission update to the calendar. Is there a way to run a script hybrid from the local DC so it will make attribute edits? There are only two users that need to be “blocked” so I could manually add those in AD. If I run the permission change and don’t add an attribute, I’m guessing it will try to rewrite them every time it runs from Azure – if I automate it.
— Error when updating an individuals attribute–
Error executing request. An Azure Active Directory call was made to keep object in sync between Azure Active Directory and Exchange Online. However, it failed. Detailed error message: Unable to update the specified properties for on-premises mastered Directory Sync objects or objects currently undergoing migration. DualWrite (Graph) RequestId: 11f87bc3-4dde-4bbc-a6e2-ba27dc17374e The issue may be transient and please retry a couple of minutes later. If issue persists, please see exception members for more information.
The two users you want to block have on-premises mailboxes? If so, you can only manage those attributes from an on-premises server. You’ll need to use Exchange Server PowerShell to update the custom attribute and synchronize it with the cloud.
Great article, just what I was looking for. Thumbs up for the good work and sharing with comunity
$Mbx = Import-CSV c:\Temp\SomeTempFile.csv
ForEach ($M in $Mbx) { Set-Mailbox -Identity $M.UserPrincipalName-CustomAtrribute13 “Blocked”}
Typo in: “Atrribute”
Thanks. Fixed!
Hi Tony! Thanks for you post!
Do you know if it is possible prevent users to modify free/busy options by itself? I see that many users hide their Free/Busy information completely by setting the permission to None. And I want to avoid that. Thanks! Fernando
I don’t believe an option exists to turn off the option for users to control sharing of free/busy information for their calendars. But you could run the script periodically to reset calendars…
Thanks Tony!!