Set-MailboxFolderPermission – Office 365 for IT Pros https://office365itpros.com Mastering Office 365 and Microsoft 365 Thu, 08 Aug 2024 14:32:48 +0000 en-US hourly 1 https://i0.wp.com/office365itpros.com/wp-content/uploads/2024/06/cropped-Office-365-for-IT-Pros-2025-Edition-500-px.jpg?fit=32%2C32&ssl=1 Set-MailboxFolderPermission – Office 365 for IT Pros https://office365itpros.com 32 32 150103932 Working with Calendar Permissions using the Microsoft Graph PowerShell SDK https://office365itpros.com/2024/06/18/set-default-calendar-permission/?utm_source=rss&utm_medium=rss&utm_campaign=set-default-calendar-permission https://office365itpros.com/2024/06/18/set-default-calendar-permission/#respond Tue, 18 Jun 2024 07:00:00 +0000 https://office365itpros.com/?p=65222

Set Calendar Permission to Allow Organization Users to See Limited Details

In September 2021, I wrote about how to set the calendar permission for mailboxes to allow users within the organization to view event titles and locations. In the article, I discuss how to use the Set-MailboxFolderPermission cmdlet to update the access rights assigned to the “default user” from availability only to limited details. The permission assigned to the default user is the one used if a more specific permission is unavailable. By allowing more access to a user calendar for the default user, it means that anyone in the organization can see more information from that user’s calendar. In OWA and the new Outlook for Windows (Monarch) client, the sharing permission is called “can view titles and locations” (Figure 1).

Can view titles and locations means that users who check someone else’s calendar to see event subjects and locations. The default shows only that slots in a calendar are blocked or free.

Using OWA to set the default user calendar permission
Figure 1: Using OWA to set the default user calendar permission

Calendar Permissions and the Graph

Time passes on and today an alternative solution is available in the form of the Graph calendar permission resource and its methods, plus the associated Microsoft Graph PowerShell SDK cmdlets like Get-MgUserCalendarPermission and Update- MgUserCalendarPermission.

The Get-MailboxFolderPermission and Set-MailboxFolderPermission cmdlets have never been quick, so the question is whether the Graph-based cmdlets are faster at checking and setting calendar permissions.

Testing Performance

I decided to test by writing two scripts. Both scripts fetch user and room mailboxes which use the limited availability permission and update the mailboxes to allow access to limited details.

Both scripts use the Get-ExoMailbox cmdlet to fetch mailbox details. There isn’t a good Graph-based method to fetch mailbox-enabled accounts. Get-MgUser can apply a filter to fetch licensed accounts, but that set won’t include room mailboxes. Get-MgUser can fetch all member accounts, but this set will probably include a bunch of accounts that don’t have mailboxes. In addition, because the script loads the Exchange Online management module to use Get-ExoMailbox, it can also use Set-Mailbox to update a custom attribute with an indicator after processing a mailbox.

Maintaining an indicator in a custom attribute is important because the Get-ExoMailbox command can filter out mailboxes that have the permission set. For instance, if you run the script monthly, it will only process mailboxes created since the last run.

Here’s the Exchange Online script. The Set-MailboxFolderPermission cmdlet requires passing the name of the calendar folder, so there’s some code to figure out the value in different languages.

# Exchange Online version 
[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, RoomMailbox -Filter {CustomAttribute10 -ne "OpenCalendar"} -ResultSize Unlimited -Properties Languages | Sort-Object DisplayName
Write-Host ("{0} mailboxes found" -f $Mbx.Count)
[int]$Updates = 0
ForEach ($M in $Mbx) {
  # Figure out the name of the Calendar folder in the user's preferred language
  [array]$Languages = $M.Languages
  Switch ($Languages[0]) {
      "en-US" { $CalendarName = "Calendar" }
      "fr-FR" { $CalendarName = "Calendrier" }
      "de-DE" { $CalendarName = "Kalender" }
      "es-ES" { $CalendarName = "Calendario" }
      "it-IT" { $CalendarName = "Calendario" }
      "nl-NL" { $CalendarName = "Agenda" }   
      Default { $CalendarName = "Calendar" }
  }
  # Build the path to the Calendar folder
  $CalendarFolder = ("{0}:\{1}" -f $M.UserPrincipalName, $CalendarName)
  [array]$Data = Get-MailboxFolderPermission -Identity $CalendarFolder | Where-Object {$_.User.usertype.value -eq "Default"} | Select-Object -ExpandProperty AccessRights
  If ([string]$Data -ne "LimitedDetails") {
      Write-Host ("Setting LimitedDetails permission for {0}" -f $M.displayName) -ForegroundColor Yellow
      Set-MailboxFolderPermission -Identity $CalendarFolder -User Default -AccessRights LimitedDetails
      Set-Mailbox -Identity $M.UserPrincipalName -CustomAttribute10 "OpenCalendar"
      $Updates++
  } Else {
      # for some reason the custom attribute is not set to reflect the calendar permission, so update it
      Write-Host "Setting custom attribute for" $M.UserPrincipalName
      Set-Mailbox -Identity $M.UserPrincipalName -CustomAttribute10 "OpenCalendar"
  }
}
Write-Host ("Calendar permission updated for {0} mailboxes" -f $Updates)

Here’s the version using a mixture of Exchange Online and Microsoft Graph PowerShell SDK cmdlet. This code doesn’t need to know anything about language values for folder names because the Graph uses different identifiers.

# Graph version
[int]$Updates = 0
[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, RoomMailbox -Filter {CustomAttribute10 -ne "OpenCalendar"} -ResultSize Unlimited -Properties Languages | Sort-Object DisplayName
Write-Host ("{0} mailboxes found" -f $Mbx.Count)
ForEach ($M in $Mbx){
    [array]$CalendarPermissions = Get-MgUserCalendarPermission -UserId $M.ExternalDirectoryObjectId
  If ($CalendarPermissions) {  
     $OrgDefault = $null
     [array]$OrgDefault = $CalendarPermissions | Where-Object {$_.EmailAddress.Name -eq "My Organization"}  
     If ($Permission -notin $OrgDefault.Role) {
        Write-Host ("Setting Limited Read permission for {1}" -f $M.DisplayName) -ForegroundColor Yellow
        Try {
           Update-MgUserCalendarPermission -UserId $M.ExternalDirectoryObjectId `
             -Role "LimitedRead" -CalendarPermissionId $OrgDefault.id | Out-Null
           $Updates++
        } Catch {
            Write-Host ("Failed to update calendar permission for {0}" -f $M.DisplayName) -ForegroundColor Red
        }
        Set-Mailbox -Identity $M.ExternalDirectoryObjectId -CustomAttribute10 "OpenCalendar"
        } Else {
          Write-Host ("{0} already has the Limited Read permission" -f $M.DisplayName)
        }
  } 
}
Write-Host ("Calendar permission updated for {0} mailboxes" -f $Updates)

Here’s the version using a mixture of Exchange Online and Microsoft Graph PowerShell SDK cmdlet. This code doesn’t need to know anything about language values for folder names because the Graph uses different identifiers. I can’t account for why Microsoft decided to call the permission LimitedDetails in Exchange and LimitedRead in the Graph. The different roles available for the Graph are documented online.

# Graph version
[int]$Updates = 0
[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, RoomMailbox -Filter {CustomAttribute10 -ne "OpenCalendar"} -ResultSize Unlimited -Properties Languages | Sort-Object DisplayName
Write-Host ("{0} mailboxes found" -f $Mbx.Count)
ForEach ($M in $Mbx){
    [array]$CalendarPermissions = Get-MgUserCalendarPermission -UserId $M.ExternalDirectoryObjectId
  If ($CalendarPermissions) {  
     $OrgDefault = $null
     [array]$OrgDefault = $CalendarPermissions | Where-Object {$_.EmailAddress.Name -eq "My Organization"}  
    If ("LimitedRead" -notin $OrgDefault.Role) {
       Write-Host ("Setting Limited Read permission for {0}" -f $M.DisplayName) -ForegroundColor Yellow
       Try {
          Update-MgUserCalendarPermission -UserId $M.ExternalDirectoryObjectId `
            -Role "LimitedRead" -CalendarPermissionId $OrgDefault.id | Out-Null
          $Updates++
       } Catch {
           Write-Host ("Failed to update calendar permission for {0}" -f $M.DisplayName) -ForegroundColor Red
       }
       Set-Mailbox -Identity $M.ExternalDirectoryObjectId -CustomAttribute10 "OpenCalendar"
       } Else {
         Write-Host ("{0} already has the Limited Read permission" -f $M.DisplayName)
       }
  } 
}
Write-Host ("Calendar permission updated for {0} mailboxes" -f $Updates)

The Measure-Command cmdlet generated the test results, which showed that the Exchange script required 2.84 seconds per mailbox to run. The Graph version was nearly a second faster per mailbox (1.96 seconds). Your mileage might vary.

No Need to Change Unless You Must

Using the Graph SDK cmdlets saves almost a second per mailbox. That doesn’t mean that you should update scripts to rip out and replace the Set-MailboxFolderPermission cmdlet. While it’s important to use code that runs quickly, this kind of script is not something you’re going to run daily. It’s more likely to run on a scheduled basis, such as an Azure Automation runbook, and you won’t notice the extra time.

Besides, the most important contribution to performance in this example is reducing the number of mailboxes to process by maintaining the indicator and using the indicator to filter mailboxes. One cmdlet might be faster than another, but it’s how you use cmdlets in a script that dictates overall performance.


So much change, all the time. It’s a challenge to stay abreast of all the updates Microsoft makes across the Microsoft 365 ecosystem. Subscribe to the Office 365 for IT Pros eBook to receive monthly insights into what happens, why it happens, and what new features and capabilities mean for your tenant.

]]>
https://office365itpros.com/2024/06/18/set-default-calendar-permission/feed/ 0 65222
How to Allow Exchange Online Users to See Availability Details in Other Calendars https://office365itpros.com/2021/09/21/exchange-view-calendar-information/?utm_source=rss&utm_medium=rss&utm_campaign=exchange-view-calendar-information https://office365itpros.com/2021/09/21/exchange-view-calendar-information/#comments Tue, 21 Sep 2021 01:00:00 +0000 https://office365itpros.com/?p=51595

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.

The Outlook for Windows scheduling assistant displays free and busy information for attendees - and to view calendar infornation
Figure 1: The Outlook for Windows scheduling assistant displays free and busy information for attendees

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).

OWA displays calendar sharing permissions, including the default for the organization
Figure 1: OWA displays calendar sharing permissions, including the default for the organization

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.

Outlook's scheduling assistant can reveal more information after mailboxes are updated
Figure 3: Outlook’s scheduling assistant can reveal more information after mailboxes are updated

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).

The scheduling assistant in the Teams calendar app displays availability information for a mailbox
The scheduling assistant in the Teams calendar app displays availability information for a mailbox

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.

]]>
https://office365itpros.com/2021/09/21/exchange-view-calendar-information/feed/ 12 51595
How to Rebuild Delegate Access for a Calendar with PowerShell https://office365itpros.com/2021/01/20/rebuild-delegate-access-calendar-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=rebuild-delegate-access-calendar-powershell https://office365itpros.com/2021/01/20/rebuild-delegate-access-calendar-powershell/#comments Wed, 20 Jan 2021 09:08:46 +0000 https://office365itpros.com/?p=40810

Delegate Access to Calendars is Popular Exchange Feature

Delegate access to a mailbox is a popular feature supported by Outlook desktop, OWA, and Outlook Mobile. In some cases, you only want to allow access to a specific folder rather than the complete mailbox. Calendar access is often granted to delegates to allow other people to deal with someone’s schedule. It’s easy for users to assign delegate access to their calendar. For instance, in OWA, go to the calendar, click the […] beside the calendar you want to share, select Sharing and permissions, and then add the new delegate. In Figure 1, we’ve elected to give the delegate the ability to view private calendar events too.

Creating a new delegate with access to a calendar with OWA
Figure 1: Creating a new delegate with access to a calendar with OWA

Once applied, the delegate will be able to open the delegator’s calendar and Exchange will send calendar invitations and responses to the delegate for their attention.

Behind the Scenes

Delegate access usually works without a hitch, but when things go wrong administrators will probably need to resort to PowerShell to understand what’s happening. The first thing is to establish what kind of access someone has to a problematic calendar. The Get-MailboxFolderPermission cmdlet shows the permissions set on a folder. In this case, we pass the user principal name of the account we want to check and “:\Calendar” to indicate the folder name.

Get-MailboxFolderPermission -Identity Jane.Sixsmith@office365itpros.com:\Calendar

FolderName           User                 AccessRights          SharingPermissionFlags
-------------           ----                 ------------       ----------------------
Calendar             Default              {AvailabilityOnly}
Calendar             Anonymous            {None}
Calendar             Ken Bowers           {Editor}              Delegate, CanViewPrivateItems

Common Delegate Access Issue

According to Microsoft, the most common error met with delegate access happens when a user cannot add a new delegate or remove an existing delegate from their mailbox. The root cause is usually a corrupted hidden item in the mailbox which stores the delegate information. Microsoft publishes a comprehensive support article outlining the steps to take to recreate the hidden item. The steps work, but assume that:

  • You have a working knowledge of the MFCMAPI utility or the Exchange Web Services editor. I prefer using MFCMAPI and consider it an extremely useful program for any administrator, but I acknowledge that the interface is “interesting” and non-intuitive. In other words, it’s easy to make mistakes.
  • You can run these utilities on a Windows workstation to access the problem mailbox.

Because of the multi-step recipe to fix the problem and the need to use an unfamiliar program, some people never manage to get to the end and resolve the issue. This is a classic example of where software can help.

Automating the Rebuild with a New Cmdlet Parameter

Microsoft has released a new switch parameter for the Remove-MailboxFolderPermission cmdlet called ResetDelegateUserCollection. When you run the cmdlet with the parameter, Exchange Online essentially does all the work outlined in the support article to replace the potentially corrupted mailbox items. For example:

Remove-MailboxFolderPermission -Identity Jane.Sixsmith@office365itpros.com:\Calendar -ResetDelegateUserCollection

Confirm
Are you sure you want to perform this action?
Using ResetDelegateUserCollection changes existing calendar Delegate permissions. You will need to re-assign the
Delegate flag to these recipients using Set-MailboxFolderPermission -SharingPermissionFlags Delegate. It is suggested
that this ResetDelegateUserCollection option is only used when you believe there is corruption that is preventing
managing calendar permissions.
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): Y
WARNING: Resetting DelegateUserCollection...
WARNING: DelegateUserCollection is reset.

Note the warning. If we run Get-MailboxFolderPermission again, we’ll see that the sharing permission flags which make someone into a delegate are gone.

Get-MailboxFolderPermission -Identity Jane.Sixsmith@office365itpros.com:\Calendar

FolderName           User                 AccessRights             SharingPermissionFlags
----------           ----                 ------------             ----------------------
Calendar             Default              {AvailabilityOnly}
Calendar             Anonymous            {None}
Calendar             Ken Bowers           {Editor}

To complete the fix, we need to add delegate permissions again. You could ask the user to do this by updating the permissions assigned to their calendar, but it’s easier and more polite for the administrator who’s just reset the delegate information to do the job for the user by running the Set-MailboxFolderPermission cmdlet. If you don’t do reset permissions, delegates will have editor permission for the calendar folder, but they won’t be able to process calendar invitations on behalf of the mailbox owner. Here’s how to reset the permissions for Ken Bowers:

Set-MailboxFolderPermission -Identity Jane.Sixsmith@office365itpros.com:\Calendar -User Ken.Bowers@office365itpros.com -SharingPermissionFlags Delegate, CanViewPrivateItems -AccessRights Editor

After the cmdlet completes, you can run Get-MailboxFolderPermission again to verify that the delegate sharing permission flag is present once again (and optionally the flag allowing the delegate to view private items too).

Of course, it’s fine if you’d prefer to follow the MFCMAPI recipe to fix the delegate issue, but it’s a lot easier and faster to run a couple of lines of PowerShell!

Cmdlet Availability

The upgraded version of Remove-MailboxFolderPermission is rolling out now. If your RBAC configuration is higher than 15.20.3722, the cmdlet should be available in your tenant. To check, run the Get-OrganizationConfig cmdlet to check the value of RBACConfigurationVersion:

Get-OrganizationConfig | Select RBACConfigurationVersion

RBACConfigurationVersion
------------------------
0.1 (15.20.3763.11)

This is just the kind of detailed how-to information we love reading about. It might only end up as a line or two in the Office 365 for IT Pros eBook, but that’s no reason not to share the knowledge with you.

]]>
https://office365itpros.com/2021/01/20/rebuild-delegate-access-calendar-powershell/feed/ 1 40810