Making Sure Apps Can Run Exchange Online Management Cmdlets

Using the Exchange.ManageAsApp Permission with Exchange Online PowerShell

Updated 7 December 2022

With the addition of support for managed identities in V3.0 of the Exchange Online management PowerShell module, developers might be more interested in creating Azure Automation runbooks that use the Exchange Online cmdlets to process data like mailboxes. In this discussion, when I refer to a managed identity, I mean a system-assigned managed identity working within an Azure Automation Account. Essentially, a managed identity is a service principal used to access Azure resources that Azure manages automatically. No access is available to the credentials for the managed identity. Like the service principals for other apps, managed identity service principals can hold permissions to allow them access to resources like apps.

As an example, it’s now easy to connect to Exchange Online in a runbook with a command like:

Connect-ExchangeOnline -ManagedIdentity -Organization office365itpros.onmicrosoft.com 

Exchange Online connects using the managed identity owned by the Azure Automation account that’s executing the runbook.

As noted above, before it can do anything interesting after connecting, the managed identity needs permissions. The essential permission for Exchange Online is Exchange.ManageAsApp, which allows an app to run Exchange Online cmdlets as if the app was an administrator account. Service principals for registered apps and managed identities both need this permission to do useful work with Exchange Online cmdlets.

Some Background

In November 2020, Microsoft announced the deprecation of the Outlook REST API. This was part of a wider effort to move developers away from legacy APIs to the Graph. Microsoft also considers Exchange Web Services (EWS) to be a legacy API, but in this instance, the Exchange team focused on the Outlook REST API, which the Graph Outlook Mail API replaces.

At the same time, Microsoft said that they “removed the Exchange app permission from the Azure portal.” The Exchange.ManageAsApp permission is one of the permissions in the Office 365 Exchange Online API. Microsoft’s action didn’t remove the ability to assign the permission to apps in the Azure AD admin center. It just made the process a little harder.

Assigning Exchange.ManageAsApp

To assign the Exchange.ManageAsApp permission to a registered app, select the app in the Registered Apps blade. Go to API permissions to add a permission as normal. When Azure AD displays the range of permissions to select from, click the APIs my organization uses tab, and then type Office 365 Exchange Online into the search box. Azure AD will find the Office 365 Exchange Online API (Figure 1). Note the application identifier shown here. We’ll need this later.

Finding the Office 365 Exchange Online API
Figure 1: Finding the Office 365 Exchange Online API

Now browse the set of permissions in the Office 365 Exchange Online API and select Exchange.ManageAsApp (Figure 2). Make sure that you’ve selected application permissions and click Add permission. When you return to the app details, consent to the assignment, just like you’d do for a Graph API permission.

Adding the Exchange.ManageAsApp permission
Figure 2: Adding the Exchange.ManageAsApp permission

The registered app can now run Exchange Online cmdlets as an administrator. That’s all well and good, but what about a managed identity?

Managed Identities are Different

Unlike registered apps, managed identities show up under the enterprise apps section of the Azure AD admin center. Open enterprise apps and apply a filter to find managed identities (Figure 3).

Selecting managed identities in the Azure AD admin center
Figure 3: Selecting managed identities in the Azure AD admin center

Azure AD lists the Azure automation accounts with managed identities. Select the automation account you want to work with. When you access its permissions, Azure AD tells you that: “The ability to consent to this application is disabled as the app does not require consent. Granting consent only applies to applications requiring permissions to access your resources.” In other words, you can’t assign an API to an automation account, or rather the service principal for the managed identity, through the Azure AD admin center.

Instead, you can do the job with PowerShell using cmdlets from the Microsoft Graph PowerShell SDK. Here’s how:

  • Note the name of the automation account used with the managed identity. In this example, the account name is “ExoAutomationAccount.”
  • Connect to the Graph with the AppRoleAssignment.ReadWrite.All permission.
  • Run the Get-MgServicePrincipal cmdlet to populate a variable with the service principal for the automation account. The filter passed to the cmdlet contains the name of the automation account.
  • Populate a variable with details of the Office 365 Exchange Online enterprise app. Microsoft installs this app for tenants to allow administrative apps to manage Exchange. The app id for the Office 365 Exchange Online app is always 00000002-0000-0ff1-ce00-000000000000.
  • Find the Manage Exchange As Application role in the set held by the Exchange Online application. This role holds the Exchange.ManageAsApp permission, so any app holding the role can use the permission.
  • Create the parameters to assign the role to the managed identity.
  • Use the New-MgServicePrincipalRoleAssignment cmdlet to assign the role.

Connect-MgGraph -Scopes AppRoleAssignment.ReadWrite.All
Select-MgProfile Beta
$ManagedIdentityApp = Get-MgServicePrincipal -Filter "displayName eq 'ExoAutomationAccount'"
$ExoApp = Get-MgServicePrincipal -Filter "AppId eq '00000002-0000-0ff1-ce00-000000000000'"
$AppPermission = $ExoApp.AppRoles | Where-Object {$_.DisplayName -eq "Manage Exchange As Application"}
$AppRoleAssignment = @{
"PrincipalId" = $ManagedIdentityApp.Id
"ResourceId" = $ExoApp.Id
"AppRoleId" = $AppPermission.Id
}
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ManagedIdentityApp.Id -BodyParameter $AppRoleAssignment

The new role assignment is effective immediately. If you make a mistake, you can remove the assignment with the Remove-MgServicePrincipalAppRoleAssignment cmdlet. Here’s how:

[Array]$SPPermissions = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ManagedIdentityApp.Id
$Role = $ExoApp.AppRoles | Where-Object {$_.DisplayName -eq "Manage Exchange As Application"}
$Assignment = $SpPermissions | Where-Object {$_.AppRoleId -eq $Role.Id}
Remove-MgServicePrincipalAppRoleAssignment -AppRoleAssignmentId $Assignment.Id -ServicePrincipalId $ManagedIdentityApp.Id

Administrator Role

The final step is to make sure that Exchange Online recognizes the automation account which hosts the managed identity as an Exchange administrator. This is done by assigning the Exchange Administrator role to the automation account’s app in the Azure AD admin center. Figure 4 shows how to add the assignment of the Exchange administrator role to the app owned by an automation account.

Making sure that the Managed Identity can act as an Exchange administrator
Figure 4: Making sure that the Managed Identity can act as an Exchange administrator

If you don’t assign the Exchange administrator role to the automation account’s app, you’ll see an error telling you that the role assigned to the app isn’t supported in this scenario when you execute the runbook. For example:

The role assigned to application 415e4ba8-635f-4689-b069-22dea1fcfdb3 isn’t supported in this scenario

Assignment a Small Pain

Perhaps Microsoft under-estimated the continuing need to assign the Exchange.ManageAsApp permission to apps when they made their November 2020 announcement. Although it’s a pain to have to go to PowerShell to assign the permission, it’s something that only needs to happen once, so it’s not too bad. I have other more serious things to moan about inside Microsoft 365.


Learn more about how the Microsoft 365 ecosystem 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.

10 Replies to “Making Sure Apps Can Run Exchange Online Management Cmdlets”

  1. I tried what you subscribed here and I was able to manage to get the admin consent in plave but when I tried the simple runbook to connect and askfor a mailbox I got this error message: The role assigned to application isn’t supported in this scenario. Please check online documentation for assigning correct Directory Roles to Azure AD Application for EXO App-Only Authentication

      1. Connect-ExchangeOnline -ManagedIdentity -Organization “xxxxx.onmicrosoft.com”
        # Get the Mailbox
        $Mailboxes = Get-Mailbox -Identity “jakke@xxxx.com”

        # Output the Results for the Mailbox
        Write-Output $Mailboxes

      2. I ran this script successfully (altered for my tenant) by changing Get-Mailbox (the old Remote PowerShell cmdlet) to Get-ExoMailbox (the REST-based version).

  2. I am able to get user mailbox information (get-mailbox -identity user@domain.com) in Azure Automation but when I tried to enable online archive I get

    “|Microsoft.Exchange.Data.Directory.InsufficientPermissionsException|Source server:CO3PR22MB3373.namprd22.prod.outlook.com doesn’t have write permission to target DC:VI1PR07A04DC004.EURPR07A004.PROD.OUTLOOK.COM. Usually it indicates that target forest isn’t an account partition of source forest. Additional information: Insufficient access rights to perform the operation.
    Active directory response: 00002098: SecErr: DSID-031514A0, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0”

    Command used to enable online archive: Enable-Mailbox -Identity user@domain.com -Archive

    The managed identity have “Manage Exchange As Application” permission and Exchange admin role. I don’t what other role it needs or limitation with system managed identity using Exchange module 3.0

    Full command:
    Connect-ExchangeOnline -ManagedIdentity -Organization OrganisationName.onmicrosoft.com
    Connect-AzAccount -Identity
    Connect-MgGraph -AccessToken ((Get-AzAccessToken -ResourceTypeName MSGraph).token)

    Enable-Mailbox -Identity user@domain.com -Archive

    1. This runbook worked for me:

      Connect-AzAccount -Identity
      $AccessToken = Get-AzAccessToken -ResourceUrl “https://graph.microsoft.com”

      # Connect to Exchange Online
      Connect-ExchangeOnline -ManagedIdentity -Organization redmondassociates.onmicrosoft.com
      Enable-Mailbox -Identity Jess.Cooper@office365itpros.com -Archive

      get-exomailbox jess.cooper@office365itpros.com -PropertySets all | fl *arch*

      IsExcludedFromServingHierarchy : False
      IsHierarchyReady : True
      IsHierarchySyncEnabled : True
      ArchiveDatabase : EURPR04DG586-db514
      ArchiveGuid : 7a906f36-8e00-4fc3-a588-cb0e289342b7
      ArchiveName : {In-Place Archive -Jess Cooper (Information Technology)}
      JournalArchiveAddress :
      ArchiveQuota : 100 GB (107,374,182,400 bytes)
      ArchiveWarningQuota : 90 GB (96,636,764,160 bytes)
      ArchiveDomain :
      ArchiveStatus : Active
      ArchiveState : Local
      AutoExpandingArchiveEnabled : False
      DisabledArchiveDatabase :
      DisabledArchiveGuid : 00000000-0000-0000-0000-000000000000
      ArchiveRelease :

      1. I created a new automation, runbook but still have the same problem. May I know what runbook runtime version you used?

        For me, I am using the following:
        -System managed identity
        -Runbook version 5.1
        -All module are version 5.1
        -Used the said role and permission you stated in your document ( Manage Exchange As Application and Exchange admin role)

      2. That’s exactly how I have it set up. Version 5.1.

        Are you able to use the runbook to set a mailbox property? For example, Set-Mailbox -Id Mbx -CustomAttribute1 “Test”

  3. >Doing Set-Mailbox -Id Mbx -CustomAttribute1 “Test”

    I still get the same error:

    |Microsoft.Exchange.Data.Directory.InsufficientPermissionsException|Source server:PH0PR13MB5949.namprd13.prod.outlook.com doesn’t have write permission to target DC:AM0PR07A04DC006.EURPR07A004.PROD.OUTLOOK.COM. Usually it indicates that target forest isn’t an account partition of source forest. Additional information: Insufficient access rights to perform the operation.
    Active directory response: 00002098: SecErr: DSID-031514A0, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0

    >Doing Get-Mailbox -Id Mbx | FL CustomAttribute*. Is without a problem.

    >I granted the managed identity global admin role but still the same. Tested on a brand new mailbox.

    >I will keep investigating this. Hopefully I have answer and will share once I find it.

Leave a Reply

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