Exchange Online Management – Office 365 for IT Pros https://office365itpros.com Mastering Office 365 and Microsoft 365 Mon, 23 Jun 2025 21:46:58 +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 Exchange Online Management – Office 365 for IT Pros https://office365itpros.com 32 32 150103932 Microsoft 365 PowerShell Modules Need Better Testing https://office365itpros.com/2025/06/25/microsoft-365-powershell-azure/?utm_source=rss&utm_medium=rss&utm_campaign=microsoft-365-powershell-azure https://office365itpros.com/2025/06/25/microsoft-365-powershell-azure/#respond Wed, 25 Jun 2025 07:00:00 +0000 https://office365itpros.com/?p=69757

Problems with Azure Automation Afflict Microsoft 365 PowerShell Modules

The recent problems with the Microsoft Graph PowerShell SDK are well documented. Suffice to say that the Graph PowerShell SDK hasn’t been very stable since V2.25. V2.26 and V2.27 just didn’t work, and although Microsoft delivered a much-improved update in V2.28 in May 2025, the Graph PowerShell SDK still has problems with Azure Automation.

In the Azure Automation environment, runbooks are configured to use a runtime version of PowerShell. When a runbook starts, Azure Automation loads the dependent modules (which must be a version that matches the runtime version) on the target server where the runbook executes. Currently, Azure Automation supports runtime versions for PowerShell V5.1, V7.1, and V7.2.

A Question of .NET

PowerShell V5.1 is the “classic” version. V7-based PowerShell is “PowerShell Core.” The V7.1 and V7.2 runtimes support .NET 6 while the latest versions of PowerShell use .NET 8. Software engineering groups don’t like supporting what they consider to be outdated software, so a decision was taken to drop support for .NET 6. The net effect was that V7.1 and V7.2 runbooks couldn’t use the Graph PowerShell SDK. The workaround was to use the PowerShell V5.1 runtime or revert to V2.25 of the Graph PowerShell SDK, which still supports .NET6.

Microsoft says that the solution will come when Azure Automation supports the PowerShell V7.4 runtime. That update was supposed to arrive by June 15, 2025. It’s late, so I cannot confirm or deny if Graph PowerShell SDK V2.28 code supports PowerShell V7.4 runbooks.

The .NET Versioning Problem Strikes Exchange

A week or so ago, a reader complained that the latest version of the Exchange Online management module (now V3.8.0) didn’t run with PowerShell V7.2 runbooks. A previous comment for the article where the issue was raised said that V3.5 was required to support PowerShell V7.2 runbooks as long ago as February 13, 2025. At the time, apart from finding a relevant Stack Overflow discussion, I didn’t pay too much attention to the problem. I guess I became accustomed to the Exchange module just working while the Graph PowerShell SDK was the problem child of the Microsoft 365 PowerShell modules.

As it turns out, the Exchange Online management module shares the same problem as the Microsoft Graph PowerShell SDK. Engineering decided to remove support for .NET 6 in V3.5.1 of the Exchange module and screwed up Azure Automation V7 runbooks. The release notes for V3.5.1 are brief and concise:

Version 3.5.1

  • Bug fixes in Get-EXOMailboxPermission and Get-EXOMailbox.
  • The module has been upgraded to run on .NET 8, replacing the previous version based on .NET 6.
  • Enhancements in Add-VivaModuleFeaturePolicy.

There’s nothing to raise awareness for tenant administrators that the change in supported .NET version will stop runbooks dead in the water. It’s easy to glance over the release notes and conclude that not much has changed and it’s therefore safe to upgrade to the new version. The problem becomes very evident when the Connect-ExchangeOnline cmdlet can’t run and as a result, every other Exchange cmdlet cannot be found (Figure 1).

An Exchange Online management runbook barfs when run by Azure Automation.

Microsoft 365 PowerShell.
Figure 1: An Exchange Online management runbook barfs when run by Azure Automation

The Need for Solid Azure Automation Support

No one denies that Microsoft must prune old software from their cloud services. It’s hard enough to keep a service running smoothly when it carries unnecessary baggage in the form of old code. But in the cases of both the Microsoft Graph PowerShell SDK and the Exchange Online Management module, it seems like the engineering groups never stopped to ask if the change might impact the ability of scripts to run. Running scripts interactively revealed no issues, but running code in an interactive session on a Windows PC (or even a Mac) is not the same as Azure Automation firing up a headless Linux server and configuring it with the software necessary to execute a runbook.

Ensuring that shipped modules support Azure Automation is a problem that can be solved by incorporating Azure Automation runbooks in the test procedures that must succeed before a new version of a module can be released. What’s more upsetting is the lack of awareness within Microsoft about why customers pay for Azure Automation to run scripts.

When a script moves from running interactively on an administrator workstation to become an Azure Automation runbook, it’s probably because the script is deemed to be important enough to run on a stable, robust, and secure environment, often on a schedule (the Windows Task Schedule should not be relied upon to run important scripts). In other words, Azure Automation is an important platform that deserves the respect and solid support of the Microsoft engineers that build PowerShell modules that can run within Azure Automation. That doesn’t seem to be the case today.

Too Much Disruption

Microsoft 365 tenants have suffered far too much disruption with PowerShell modules over the last few years. The retirement of the old Azure AD and MSOL modules was a necessary evil, but Microsoft didn’t handle the situation as well as they should. Many sins might be forgiven if the Microsoft 365 PowerShell modules were rock solid. They’re not currently. Let’s hope that Microsoft does a better job in their testing and pre-release verification processes for PowerShell modules in the future.


Need some assistance to write and manage PowerShell scripts for Microsoft 365? Get a copy of the Automating Microsoft 365 with PowerShell eBook, available standalone or as part of the Office 365 for IT Pros eBook bundle.

]]>
https://office365itpros.com/2025/06/25/microsoft-365-powershell-azure/feed/ 0 69757
Making Sure Apps Can Run Exchange Online Management Cmdlets https://office365itpros.com/2022/10/13/exchange-online-powershell-app/?utm_source=rss&utm_medium=rss&utm_campaign=exchange-online-powershell-app https://office365itpros.com/2022/10/13/exchange-online-powershell-app/#comments Thu, 13 Oct 2022 01:00:00 +0000 https://office365itpros.com/?p=57424

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.

]]>
https://office365itpros.com/2022/10/13/exchange-online-powershell-app/feed/ 10 57424
How to Get and Update the Exchange Online Management PowerShell Module https://office365itpros.com/2020/09/22/exchange-online-powershell/?utm_source=rss&utm_medium=rss&utm_campaign=exchange-online-powershell https://office365itpros.com/2020/09/22/exchange-online-powershell/#comments Tue, 22 Sep 2020 01:00:32 +0000 https://office365itpros.com/?p=28074

Latest Module of Exchange Online PowerShell Module is 3.1 (January 2023)

Last Updated: January 9, 2023

Exchange Online PowerShell V3.0 in the PowerShell Gallery
The Exchange Online Management PowerShell module in the PowerShell Gallery

V3.1

Released on January 9, 2023, this version removes the dependency for basic authentication through the WinRM component. V3.1 completes the transition for Exchange Online Management cmdlets to use the REST API instead of Remote PowerShell and lays the foundation for the removal of remote PowerShell connections to Exchange Online (now due in September 2023).

V3.0

On September 20, 2022, Microsoft released V3.0 of the Exchange Online Management module. The updated module is available in the PowerShell gallery. The highlights of the release include:

  • Support for certificate-based authentication (app-based authentication) for the cmdlets accessed through the Compliance endpoint.
  • Virtually all of the older (non EXO-) cmdlets now use the REST API. This means that the module no longer needs to use Basic authentication in WinRM. The fact that the cmdlets are now REST-based means that they perform better and are more robust against transient failures.
  • Support for managed identities in Azure Automation runbook scripts.

See this page for more information.

V2.0.5

On May 11, Microsoft released V2.0.5 of the Exchange Online Management PowerShell module to general availability. This is an update of what’s sometimes called Exchange Online PowerShell V2 (introduced at Ignite 2019). It is recommended that you update to the latest version at your earliest convenience.

The case for using the Exchange Online Management module instead of the older remote PowerShell cmdlets has been made many times. By now it should be a no-brainer, especially with Microsoft’s avowed intention to remove basic authentication for PowerShell as soon as possible and the consequent need to upgrade interactive PowerShell sessions and background scripts to use modern authentication. Here are the highlights of recent releases.

New Cmdlets (2.0.5)

V2.0.5 contains the cmdlets needed to manage the Ownerless Group policy (Get/Set-OwnerlessGroupPolicy) and features in the Viva Insights app for Teams (Get/Set-VivaInsightsSettings).

Support for Linux and MacOS (2.0.4)

As announced at Ignite 2020, this is the version version of the Exchange Online Management module to support Linux and MacOS. For Linux, you need to run Ubuntu version 18.04 or above. For MacOS, it’s Mojave (10.14), Catalina (10.15), and Big Sur (11) and above.

More Secure Connections (2.0.4)

In PowerShell 7, the 2.0.4 module supports browser-based single sign on. See this page for more information.

Real-time policy evaluation (Continuous Access Evaluation or CAE) is supported.

Updated Cmdlets (2.0.4)

The cmdlets used to update user preferences for MyAnalytics have been renamed to make their use more obvious.

Get-UserAnalyticsConfig is now Get-MyAnalyticsFeatureConfig.

Set-UserAnalyticsConfig is now Set-MyAnalyticsFeatureConfig.

The Get-ExoMailboxStatistics cmdlet supports two new properties: LastUserActionTime and LastInteractionTime.

Certified Connections (2.0.3)

The Exchange Online Management module comes with full support for modern authentication, multi-factor authentication, and now (in this version), certificate-based authentication (CBA) to allow scripts to run unattended as background jobs. Certificates can be stored in the certificate store of the local machine or current user. You can also use the CertificateFilePath parameter for the Connect-ExchangeOnline cmdlet to specify the file path to a .pfx file for a certificate. For more information, see this page.

Simultaneous Connections (2.0.3)

Following previous releases of the module, I complained bitterly that running the Connect-IPPSSession cmdlet to connect to the Security and Compliance endpoint removed the session connected to Exchange Online. In other words, you couldn’t do something like run Get-ExoMailbox to fetch a list of mailboxes, then run Connect-IPPSSession, do some work, and then run Get-ExoMailbox again. I may have used some bad words to fully express my opinion on the inanity of this approach.

The developers listened and V2.0.3 includes support for simultaneous connections to Exchange Online and the Security and Compliance endpoints.

Faster Connections (2.0.3)

One of the original characteristics of using the REST-based cmdlets like Get-ExoMailbox or Get-ExoMailboxStatistics was a need to “warm up” the connection. In other words, it took a while for the first connection to be established and ready for use. Microsoft says that V2.0.3 is much faster at making the initial connection and in practice it seems like the improvement is marked. Results will vary depending on the cmdlet and number of objects in the tenant, but the connections are certainly snappier than before.

Limited Cmdlet Imports (2.0.3)

Only 17 cmdlets are in the Exchange Online Management module, but when you connect to Exchange Online, over 700 cmdlets are imported into the session, all of which demand some memory. If you want to restrict memory usage to a minimum, you can specify the list of cmdlets needed by a session or script when you run the Connect-ExchangeOnline cmdlet. For example, this command will create a session with the 17 cmdlets from the module plus two imported from Exchange Online:

Connect-ExchangeOnline -CommandName Set-Mailbox, Set-CASMailbox

After the session starts, you will only be able to run Set-Mailbox and Set-CASMailbox from the set available for Exchange Online. Other cmdlets like Get-PublicFolder, New-TransportRule, or Get-UnifiedGroup are unavailable.

Take Care with Updates

When you do update the Exchange Online Management module, make sure that you include the Scope parameter to force the install of the module files onto the local disk. Otherwise you might end up like me and have some modules in OneDrive for Business and others local, with all the confusion that entails. After removing all traces of previous versions to give myself a clean start, I ran:

Install-Module ExchangeOnlineManagement -Scope AllUsers -Force

To check that the module is in the right place, run the command below and make sure that the module isn’t located in OneDrive for Business:

Get-Module ExchangeOnlineManagement | Select Path
Path
----
C:\Program Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\2.0.3\ExchangeOnlineManag...

For more information and lots of examples of using PowerShell to manage Exchange Online, subscribe to the Office 365 for IT Pros eBook.

]]>
https://office365itpros.com/2020/09/22/exchange-online-powershell/feed/ 17 28074
Microsoft Updates Exchange Online Management PowerShell Module https://office365itpros.com/2020/02/25/microsoft-updates-exchange-online-management-powershell-module/?utm_source=rss&utm_medium=rss&utm_campaign=microsoft-updates-exchange-online-management-powershell-module https://office365itpros.com/2020/02/25/microsoft-updates-exchange-online-management-powershell-module/#comments Tue, 25 Feb 2020 00:02:58 +0000 https://office365itpros.com/?p=6623

Easy-to-Apply Upgrade for Nine-Cmdlet Module

Microsoft has updated the REST-based Exchange Online Management PowerShell module. This is an important release that you should upgrade to as soon as possible. To upgrade, run the following command from a PowerShell session with administrative permissions:

# Upgrade to the latest version of the Exchange Online Management module
Update-Module ExchangeOnlineManagement -RequiredVersion 0.3582.0

After the upgrade completes, check that you’re using the right module with:

Get-Module |?{$_.Name -eq "ExchangeOnlineManagement"}| Select Name, Version

Name                     Version
----                     -------
ExchangeOnlineManagement 0.3582.0

Version 0.3582.0 is the latest release of the Exchange Online Management module available at the time of writing. It might be newer when you upgrade. As you can see by the zero used for the major version number, this module is still a preview release.

The developers have included some release notes with the module:

(Find-Module 
# Access release notes for the Exchange Online Management module
(Get-Module ExchangeOnlineManagement).ReleaseNotes

Bug Fixes and Upgrades

Apart from several security and other bug fixes in the new module, the new module contains four important updates:

  • The date field returned by the REST cmdlets should now be formatted in the locale of the workstation (I complained about the problem in this article). I see some instances of invalid date formats being reported by the cmdlets, so the developers have some more work to do here.
  • Support added for using the cmdlets to manage Exchange in a different tenant via the AzureADAuthorizationEndpointUri parameter for the Connect-ExchangeOnline cmdlet.
  • Previously, if you ran Connect-ExchangeOnline and passed it a PSCredential object in the Credentials parameter, the credentials object and any access tokens would be emptied. You’d connect to Exchange Online but would need to re-enter credentials to connect to any other PowerShell endpoint (like Azure Active Directory or Teams).
  • The Alias and DisplayName properties of mailboxes can be used as input identities for the REST cmdlets. Previously, the cmdlets limited identities to the object identifier and user principal name of accounts.

Frequent Updates

As always, it’s a good idea to check for module updates periodically to ensure that you don’t miss out on bug fixes. The Exchange Online Management is still in preview, so more bugs are expected, and change will be faster.

Because these cmdlets deliver great performance and reliability benefits when dealing with very large sets of Exchange objects, some are looking for a way to run them in a secure manner in background processes. I know that this is high on the list of what the engineers want to do in the near future, so that’s another good reason to keep checking for updates.


The Office 365 for IT Pros eBook includes hundreds of practical examples of PowerShell in use to manage Exchange and other workloads. Upgrade your knowledge with the best Office 365 book on the market.

]]>
https://office365itpros.com/2020/02/25/microsoft-updates-exchange-online-management-powershell-module/feed/ 1 6623