Improved handling of Mailbox permissions in Exchange Online

As I was making some changes to the Mailbox permissions inventory script, I noticed few new parameters made available for the Get-MailboxPermission cmdlet. So it was only natural to take them for a spin.

The parameters in question include -IncludeUnresolvedPermissions and -IncludeSoftDeletedUserPermissions, as well as the generic -SoftDeletedMailbox. Here are their corresponding descriptions from the online help document:

  • IncludeSoftDeletedUserPermissions – returns permissions from soft-deleted mailbox users in the results. In other words, if you have granted access to a given user, and then soft-deleted his account, you can use the –IncludeSoftDeletedUserPermissions switch to return such entries in the Get-MailboxPermission cmdlet output. If you do not specify the switch, entries corresponding to soft-deleted mailboxes will be omitted.
  • IncludeUnresolvedPermissions – returns unresolved permissions in the results. Those correspond to entries that no longer exist in the directory, aka orphaned entries.
  • SoftDeletedMailbox – is required to return soft-deleted mailboxes in the results. This also includes any inactive mailboxes. Use the switch when you want to include soft-deleted/inactive mailboxes in your report, without it a “object not found” error will be thrown.

Since an example is worth a thousand words, here’s how the aforementioned parameters can be used. Let’s say we have a mailbox called “shared”, and we’ve granted few people Full access permissions over it. Here’s what the Get-MailboxPermission output looks like, with the NT AUTHORITY\SELF entries removed for brevity:

C:\> Get-MailboxPermission shared

AccessRights : {FullAccess}
Deny : False
InheritanceType : All
User : vasil@michevdev3.onmicrosoft.com
UserSid : S-1-5-21-4288531086-171750275-1771573367-6121987
Identity : shared
IsInherited : False
IsValid : True
ObjectState : Unchanged

AccessRights : {FullAccess}
Deny : False
InheritanceType : All
User : huku@pta.michev.info
UserSid : S-1-5-21-4288531086-171750275-1771573367-8593717
Identity : shared
IsInherited : False
IsValid : True
ObjectState : Unchanged

Let’s say we now remove the huku@pta.michev.info user, putting it into a soft-deleted state. What happens with the permissions? If we run the Get-MailboxPermission cmdlet again, we will notice that the entry is missing. If we specify the -IncludeSoftDeletedUserPermissions parameter as well however, we will see the entry is still present, as illustrated on the screenshot below.

C:\> Remove-Mailbox huku@pta.michev.info

Confirm
Are you sure you want to perform this action?
Removing the mailbox Identity:"huku@pta.michev.info" will mark the mailbox and the archive, if present, for deletion. The associated Windows Live ID "huku@pta.michev.info" will also be deleted and
will not be available for any other Windows Live service.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):

C:\> Get-MailboxPermission shared -User huku@pta.michev.info
Write-ErrorMessage : |Microsoft.Exchange.Configuration.Tasks.ThrowTerminatingErrorException|User or group "huku@pta.michev.info" wasn't found. Please make sure you've typed it correctly.
At D:\Temp\tmpEXO_25s4ai4l.ge4\tmpEXO_25s4ai4l.ge4.psm1:1109 char:13
+ Write-ErrorMessage $ErrorObject $IsFromBatchingRequest
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-MailboxPermission], ThrowTerminatingErrorException
+ FullyQualifiedErrorId : [Server=AS8P190MB1367,RequestId=b0aaf82d-bca1-3461-c8a5-00e325786583,TimeStamp=Sun, 21 Aug 2022 12:15:38 GMT],Write-ErrorMessage

C:\> Get-MailboxPermission shared -User huku@pta.michev.info -IncludeSoftDeletedUserPermissions

AccessRights : {FullAccess}
Deny : False
InheritanceType : All
User : huku@pta.michev.info
UserSid : S-1-5-21-4288531086-171750275-1771573367-8593717
Identity : shared
IsInherited : False
IsValid : True
ObjectState : Unchanged

And this is what the –IncludeSoftDeletedUserPermissions parameter is used for, in a nutshell. If at some point later you recover the soft-deleted mailbox, the permission entry will auto-appear in the “regular” Get-MailboxPermission output, and you no longer need to specify the switch. The –IncludeUnresolvedPermissions switch works in a similar fashion, but for “orphaned” entries. The biggest difference between the two is that you cannot “recover” orphaned entries.

Lastly, let’s also showcase how the -SoftDeletedMailbox switch works. Basically, you use it to force the Get-MailboxPermission cmdlet to return output for soft-deleted (and/or inactive) mailboxes. Without the parameter, an error will be thrown. With it, you can expect the regular output to appear:

C:\> Get-MailboxPermission huku@pta.michev.info
Write-ErrorMessage : ExE610C8|Microsoft.Exchange.Configuration.Tasks.ManagementObjectNotFoundException|Couldn't find 'huku@pta.michev.info' as a recipient.
At D:\Temp\tmpEXO_25s4ai4l.ge4\tmpEXO_25s4ai4l.ge4.psm1:1109 char:13
+ Write-ErrorMessage $ErrorObject $IsFromBatchingRequest
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-MailboxPermission], ManagementObjectNotFoundException
+ FullyQualifiedErrorId : [Server=AS8P190MB1367,RequestId=f61b110c-e9c0-e33d-3004-633e2ea6fdc2,TimeStamp=Sun, 21 Aug 2022 12:26:28 GMT],Write-ErrorMessage

C:\> Get-MailboxPermission huku@pta.michev.info -SoftDeletedMailbox

AccessRights : {FullAccess, ReadPermission}
Deny : False
InheritanceType : All
User : NT AUTHORITY\SELF
UserSid : S-1-5-10
Identity : Soft Deleted Objects\huku
IsInherited : False
IsValid : True
ObjectState : Unchanged

An interesting thing to note in the output is that the identity of the soft-deleted object is prefixed with “Soft Deleted Objects”, which is the name of the Organizational Unit where such objects are stored. On the other hand, the User property value returned for permissions granted to soft-deleted mailboxes does not include the prefix, which makes it a bit harder to handle.

Speaking about the output, you might also note that the UserSid property is now returned. Unfortunately, the Get-Mailbox cmdlet does not resolve SID values, and while you can use the Get-User cmdlet instead, this one does not support the -SoftDeletedMailbox switch (whereas Get-Mailbox does). But, there is a workaround you can use here too – specify the –OrganizationalUnit parameter with value of “Soft Deleted Objects” and voila:

C:\> Get-User S-1-5-21-4288531086-171750275-1771573367-8593717
Write-ErrorMessage : Ex6F9304|Microsoft.Exchange.Configuration.Tasks.ManagementObjectNotFoundException|The operation couldn't be performed because object
'S-1-5-21-4288531086-171750275-1771573367-8593717' couldn't be found on 'DBBPR01A07DC006.EURPR01A007.PROD.OUTLOOK.COM'.
At D:\Temp\tmpEXO_25s4ai4l.ge4\tmpEXO_25s4ai4l.ge4.psm1:1109 char:13
+ Write-ErrorMessage $ErrorObject $IsFromBatchingRequest
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [get-User], ManagementObjectNotFoundException
+ FullyQualifiedErrorId : [Server=AS8P190MB1367,RequestId=2e0567ad-347e-895a-8ffe-da3f86c92d32,TimeStamp=Sun, 21 Aug 2022 12:34:45 GMT],Write-ErrorMessage

C:\> Get-User S-1-5-21-4288531086-171750275-1771573367-8593717 -OrganizationalUnit "Soft Deleted Objects"

IsSecurityPrincipal : True
SamAccountName : huku57943-1091673623
Sid : S-1-5-21-4288531086-171750275-1771573367-8593717
SidHistory : {}
UserPrincipalName : huku@pta.michev.info
...

And while we’re discussing working/non-working parameters, it looks like the -Gr0upMailbox switch of the Get-MailboxPermission cmdlet cannot be used against any Unified group identifier. Which is fine I suppose, as we still don’t have a way of granting mailbox-level permissions on Group mailbox objects.

One more thing – we can now grant permissions to service principal objects too! To do this, you first need to “copy” the service principal object and create a representation of it within ExODS. Don’t ask me why Microsoft isn’t doing this automatically, it is what it is. Anyway, to create an (ExO) Service principal, use the New-ServicePrincipal cmdlet and provide values for the –AppId (clientID) and –ServiceId (objectId) parameters, and optional –DisplayName. For example:

New-ServicePrincipal -AppId ae23ad05-xxxx-xxxx-xxxx-78b7a0757f5f -ServiceId 2a63aee1-xxxx-xxxx-xxxx-d40971066292 -DisplayName "Service Principal for ExOPS app"

Interestingly enough, NO validation is made for the values you provide, so you can create something at random. Which makes it that more important to carefully fetch the real values from either the Azure AD UI, PowerShell or the Graph API!

Once the Service principal object has been created, you can use it to delegate permissions. To obtain a list of service principal objects, use the Get-ServicePrincipal cmdlet. Even though a new value for RecipientTypeDetails seems to have been added, ServicePrinciple (note the different spelling!), it’s not currently possible to query service principal objects via Get-Recipient or any other cmdlet, only the Get-ServicePrincipal works. Anyway, to grant permissions, use the familiar syntax:

Add-MailboxPermission sharednew -User 2a63aee1-db17-489d-a8ab-d40971066292 -AccessRights FullAccess -AutoMapping $false

-------- ---- ------------ ----------- ----
sharednew EURPR03A001\$K0NE... {FullAccess} False False

And you can of course query the permissions:

Get-MailboxPermission sharednew -User 2a63aee1-db17-489d-a8ab-d40971066292 | fl * -Force

PSComputerName : outlook.office365.com
PSShowComputerName : False
AccessRights : {FullAccess}
Deny : False
InheritanceType : All
User : 2a63aee1-db17-489d-a8ab-d40971066292
UserSid : S-1-5-21-3675944716-2045640655-299186705-56056852
IsInherited : False
IsValid : True
ObjectState : Unchanged

Only Full mailbox permissions seem to be supported at this point, you cannot delegate folder-level access to a service principal object.

Lastly, it’s worth mentioning that we can still use the –ReadFromDomainController parameter to force the full mailbox object to be returned. Unfortunately, this only works for the mailbox for which we’re querying the permissions, but still it’s a valuable way to peek behind the curtain of the Exchange Online directory.

This entry was posted in Exchange Online, Microsoft 365, Office 365, PowerShell. Bookmark the permalink.

One Response to Improved handling of Mailbox permissions in Exchange Online

  1. Pingback: More on service principal permissions in Exchange Online | Blog

Leave a Reply

Your email address will not be published.

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