The Exchange Online PowerShell module uses modern authentication and works with or without multi-factor authentication (MFA) for connecting to all Exchange-related PowerShell environments in Microsoft 365: Exchange Online PowerShell, Security & Compliance PowerShell, and standalone Exchange Online Protection (EOP) PowerShell.
For connection instructions using the module, see the following articles:
The rest of this article explains how the module works, how to install and maintain the module, and the optimized Exchange Online cmdlets that are available in the module.
Tip
Version 3.0.0 and later (2022) is known as the Exchange Online PowerShell V3 module (abbreviated as the EXO V3 module). Version 2.0.5 and earlier (2021) was known as the Exchange Online PowerShell V2 module (abbreviated as the EXO V2 module).
REST API connections in the EXO V3 module
Exchange Online PowerShell and Security & Compliance PowerShell now use REST API connections for all cmdlets:
Exchange Online PowerShell: EXO V3 module v3.0.0 or later.
Security & Compliance PowerShell: EXO V3 module v3.2.0 or later.
Cmdlets in REST API connections have the following advantages over their historical counterparts:
More secure: Built-in support for modern authentication and no dependence on the remote PowerShell session. PowerShell on your client computer doesn't need Basic authentication in WinRM.
More reliable: Transient failures use built-in retries, so failures or delays are minimized. For example:
Failures due to network delays.
Delays due to large queries that take a long time to complete.
Better performance: REST API connections avoid setting up a PowerShell runspace.
The benefits of cmdlets in REST API connections are described in the following table:
Remote PowerShell cmdlets
Get-EXO* cmdlets
REST API cmdlets
Security
Least secure
Highly secure
Highly secure
Performance
Low performance
High performance
Medium performance
Reliability
Least reliable
Highly reliable
Highly reliable
Functionality
All parameters and output properties available
Limited parameters and output properties available
All parameters and output properties available
REST API cmdlets have the same cmdlet names and work just like their remote PowerShell equivalents, so you don't need to update cmdlet names or parameters in older scripts.
Basic authentication (remote PowerShell) connections are deprecated in Exchange Online PowerShell and Security & Compliance PowerShell. For more information, see here and here.
A few cmdlets in Exchange Online PowerShell have been updated with the experimental UseCustomRouting switch in REST API connections. This switch routes the command directly to the required Mailbox server, and might improve overall performance. Use the UseCustomRouting switch experimentally.
When you use the UseCustomRouting switch, you can use only the following values for identity of the mailbox:
User principal name (UPN)
Email address
Mailbox GUID
The UseCustomRouting switch is available only on the following Exchange Online PowerShell cmdlets in REST API connections:
Get-Clutter
Get-FocusedInbox
Get-InboxRule
Get-MailboxAutoReplyConfiguration
Get-MailboxCalendarFolder
Get-MailboxFolderPermission
Get-MailboxFolderStatistics
Get-MailboxMessageConfiguration
Get-MailboxPermission
Get-MailboxRegionalConfiguration
Get-MailboxStatistics
Get-MobileDeviceStatistics
Get-UserPhoto
Remove-CalendarEvents
Set-Clutter
Set-FocusedInbox
Set-MailboxRegionalConfiguration
Set-UserPhoto
Use the Get-ConnectionInformation cmdlet to get information about REST API connections to Exchange Online PowerShell and Security & Compliance PowerShell. This cmdlet is required because the Get-PSSession cmdlet in Windows PowerShell doesn't return information for REST API connections.
Scenarios where you can use Get-ConnectionInformation are described in the following table:
Scenario
Expected output
Run after Connect-ExchangeOnline or Connect-IPPSSession commands for REST API connections.
Returns one connection information object.
Run after multiple Connect-ExchangeOnline or Connect-IPPSSession commands for REST API connections.
Returns a collection of connection information objects.
Use the SkipLoadingFormatData switch on the Connect-ExchangeOnline cmdlet to avoid loading format data and to run Connect-ExchangeOnline commands faster.
Cmdlets backed by the REST API have a 15-minute timeout, which can affect bulk operations. For example, the following Update-DistributionGroupMember command to update 10,000 members of a distribution group might time out:
Instead, use the Update-DistributionGroupMember command to update fewer members, and then add the remaining members individually using an Add-DistributionGroupMember command. For example:
For more information about what's new in the EXO V3 module, see the Release notes section later in this article.
Report bugs and issues for Preview versions of the Exchange Online PowerShell module
Tip
For General Availability (GA) versions of the module, don't use the following email address to report issues. Messages about GA versions of the module won't be answered. Instead, open a support ticket.
For Preview versions of the module, use exocmdletpreview[at]service[dot]microsoft[dot]com to report any issues that you might encounter. Be sure to include the log files in your email message. To generate the log files, replace <Path> with an output folder, and then run the following command:
PowerShell
Connect-ExchangeOnline -EnableErrorReporting -LogDirectoryPath <Path> -LogLevel All
Cmdlets in the Exchange Online PowerShell module
The EXO module contains nine exclusive Get-EXO* cmdlets that are optimized for speed in bulk data retrieval scenarios (thousands and thousands of objects) in Exchange Online PowerShell. The improved cmdlets in the module are listed in the following table:
If you open multiple connections to Exchange Online PowerShell in the same window, the Get-EXO* cmdlets are always associated with the last (most recent) Exchange Online PowerShell connection. Run the following command to find the REST API session where the Get-EXO* cmdlets are run: Get-ConnectionInformation | Where-Object {$_.ConnectionUsedForInbuiltCmdlets -eq $true}.
The connection-related cmdlets in the module are listed in the following table:
Frequent use of the Connect-ExchangeOnline and Disconnect-ExchangeOnline cmdlets in a single PowerShell session or script might lead to a memory leak. The best way to avoid this issue is to use the CommandName parameter on the Connect-ExchangeOnline cmdlet to limit the cmdlets that are used in the session.
Miscellaneous Exchange Online cmdlets that happen to be in the module are listed in the following table:
If you connect to Exchange Online PowerShell from a network that's behind a proxy server, the EXO V2 module (version v2.0.5 or earlier) doesn't work in Linux. You need to use the EXO V3 module (v3.0.0 or later) in Linux to connect from a network that's behind a proxy server.
Windows
All versions of the module are supported in Windows PowerShell 5.1.
PowerShell 7 on Windows requires version 2.0.4 or later.
Version 2.0.5 or later of the module requires the Microsoft .NET Framework 4.7.2 or later to connect. Otherwise, you get a System.Runtime.InteropServices.OSPlatform error. This requirement shouldn't be an issue in current versions of Windows. For more information about versions of Windows that support the .NET Framework 4.7.2, see this article.
Windows PowerShell requirements and module support in older versions of Windows are described in the following list:
² Support for this version of Windows has ended, and is now supported only in Azure virtual machines.
³ This version of Windows supports only v2.0.3 or earlier versions of the module.
⁴ Windows PowerShell 5.1 on this version of Windows requires the .NET Framework 4.5 or later and the Windows Management Framework 5.1. For more information, see Windows Management Framework 5.1.
Prerequisites for the Exchange Online PowerShell module
Set the PowerShell execution policy to RemoteSigned
Tip
The settings in this section apply to all versions of PowerShell on all operating systems.
PowerShell needs to be configured to run scripts, and by default, it isn't. You get the following error when you try to connect:
Files cannot be loaded because running scripts is disabled on this system. Provide a valid certificate with which to sign the files.
To require all PowerShell scripts that you download from the internet are signed by a trusted publisher, run the following command in an elevated PowerShell window (a PowerShell window you open by selecting Run as administrator):
REST API connections don't require Basic authentication in WinRM as described in this section. As described earlier in this article, Basic authentication (remote PowerShell) access to Exchange Online PowerShell and Security & Compliance PowerShell are deprecated. The information in this section is maintained for historical purposes.
For remote PowerShell connections that don't use the REST API (which are now impossible), WinRM needs to allow Basic authentication. We don't send the username and password combination. The Basic authentication header is required to send the session's OAuth token, because the client-side implementation of WinRM doesn't support OAuth.
To verify that Basic authentication is enabled for WinRM, run the following command in a Command Prompt or Windows PowerShell:
Note
The following commands require that WinRM is enabled. To enable WinRM, run the following command: winrm quickconfig.
DOS
winrm get winrm/config/client/auth
If you don't see the value Basic = true, you need to run one of the following commands to enable Basic authentication for WinRM:
In a Command Prompt:
DOS
winrm set winrm/config/client/auth @{Basic="true"}
In Windows PowerShell:
PowerShell
winrm set winrm/config/client/auth '@{Basic="true"}'
If Basic authentication for WinRM is disabled, you get one of the following errors when you try to connect using a Basic authentication (remote PowerShell) connection:
The WinRM client cannot process the request. Basic authentication is currently disabled in the client configuration. Change the client configuration and try the request again.
Create Powershell Session is failed using OAuth.
PowerShellGet for REST API connections in Windows
REST API connections in Windows require the PowerShellGet module, and by dependency, the PackageManagement module. Consideration for these modules is more for PowerShell 5.1 than PowerShell 7, but all versions of PowerShell benefit from having the latest versions of the modules installed. For installation and update instructions, see Installing PowerShellGet on Windows.
Tip
Beta versions of the PackageManagement or PowerShellGet modules might cause connection issues. If you have connection issues, verify that you don't have Beta versions of the modules installed by running the following command: Get-InstalledModule PackageManagement -AllVersions; Get-InstalledModule PowerShellGet -AllVersions.
If you don't have PowerShellGet installed when you try to create a REST API connection, you get the following error when you try to connect:
Cannot find a cmdlet Update-Manifest
Install the Exchange Online PowerShell module
To install the module for the first time, complete the following steps:
Now you can use the Install-Module cmdlet to install the module from the PowerShell Gallery. Typically, you want the latest public version of the module, but you can also install a Preview version if any are available.
To install the latest public version of the module, run one of the following commands:
If the module is installed in C:\Program Files\WindowsPowerShell\Modules, it's installed for all users. If the module is installed in your Documents folder, it's installed only for the current user account.
You can use the Update-Module cmdlet to update the module from the PowerShell Gallery. Typically, you want the latest public version of the module, but you can also upgrade to a Preview version if any are available.
To upgrade to the latest public version of the module, run one of the following commands based on how you originally installed the module (all users vs. only for the current user account):
To upgrade to a Preview version of the module, you can upgrade to the latest available Preview version, or you can use the RequiredVersion parameter to upgrade to a specific Preview version.
To see the available Preview versions of the module, run the following command:
For detailed syntax and parameter information, see Update-Module.
Troubleshoot installing the Exchange Online PowerShell module
You receive one of the following errors:
The specified module 'ExchangeOnlineManagement' with PowerShellGetFormatVersion '<version>' isn't supported by the current version of PowerShellGet. Get the latest version of the PowerShellGet module to install this module, 'ExchangeOnlineManagement'.
WARNING: Unable to download from URI 'https://go.microsoft.com/fwlink/?LinkID=627338&clcid=0x409' to ''.
WARNING: Unable to download the list of available providers. Check your internet connection.
Update your installation of the PowerShellGet module to the latest version as described in Installing PowerShellGet. Be sure to close and re-open the PowerShell window before you attempt to update the ExchangeOnlineManagement module again.
You receive the following error:
No match was found for the specified search criteria and module name 'ExchangeOnlineManagement'. Try running Get-PSRepository to see all available registered module repositories.
The default repository for PowerShell modules isn't set to PSGallery. To fix this error, run the following command:
PowerShell
Register-PSRepository -Default
As of April 2020, the PowerShell Gallery only supports connections using TLS 1.2 or later. For more information, see PowerShell Gallery TLS Support.
To check your current settings in the Microsoft .NET Framework, run the following command in Windows PowerShell:
PowerShell
[Net.ServicePointManager]::SecurityProtocol
As described in the PowerShell Gallery TLS Support article, to temporarily change the security protocol to TLS 1.2 to install the PowerShellGet or ExchangeOnlineManagement modules, run the following command in Windows PowerShell before you install the module:
To permanently enable strong cryptography in the Microsoft .NET Framework version 4.x or later, run one of the following commands based on your Windows architecture:
If the module is installed in C:\Program Files\WindowsPowerShell\Modules, it was installed for all users. If the module is installed in your Documents folder, it was installed only for the current user account.
To uninstall the module, run the following command in one of the following environments based on how you originally installed the module (all users vs. only for the current user account):
In an elevated PowerShell window (all users).
In a normal PowerShell window (only for the current user account).
PowerShell
Uninstall-Module -Name ExchangeOnlineManagement
For detailed syntax and parameter information, see Uninstall-Module.
Properties and property sets in the Exchange Online PowerShell module
Traditional Exchange Online cmdlets return all possible object properties, including many blank or uninteresting properties. This behavior causes degraded performance (more server computation and added network load). You rarely (if ever) need the full complement of properties in the cmdlet output.
The Get-EXO* cmdlets in the module have categorized output properties. Instead of giving all properties equal importance and returning them in all scenarios, we categorized specific related properties into property sets. These property sets are buckets of two or more related properties on the cmdlet.
The biggest and most used Get-EXO* cmdlets use property sets:
Properties: This parameter accepts one or more property names separated by commas.
You can use the PropertySets and Properties parameters together in the same command.
We also included a Minimum property set that includes a bare minimum set of required properties for the cmdlet output (for example, identity properties). The properties in the Minimum property sets are also described in Property sets in Exchange Online PowerShell module cmdlets.
If you don't use the PropertySets or Properties parameters, you automatically get the properties in the Minimum property set.
If you use the PropertySets or Properties parameters, you get the specified properties and the properties in the Minimum property set.
Either way, the cmdlet output contains far fewer properties, and the results are returned much faster.
For example, after you connect to Exchange Online PowerShell, the following example returns only the properties in the Minimum property set for the first 10 mailboxes.
PowerShell
Get-EXOMailbox -ResultSize10
In contrast, the output of the same Get-Mailbox command would return at least 230 properties for each of the first 10 mailboxes.
Note
Although the PropertySets parameter accepts the value All, we highly discourage using this value to retrieve all properties, because it slows down the command and reduces reliability. Always use the PropertySets and Properties parameters to retrieve the minimum number of properties that are required for your scenario.
Unless otherwise noted, the current release of the Exchange Online PowerShell module contains all features of previous releases.
Current release
Version 3.7.1
Added a new property named ExoExchangeSecurityDescriptor to the output of Get-EXOMailbox that's similar to the ExchangeSecurityDescriptor property in the output of Get-Mailbox.
Added new cmdlets to support the Viva Org Insights Delegation feature:
Add-VivaOrgInsightsDelegatedRole
Get-VivaOrgInsightsDelegatedRole
Remove-VivaOrgInsightsDelegatedRole
Previous releases
Version 3.7.0
Integrated Web Account Manager (WAM) in authentication flows to enhance security.
Command line help for Exchange Online PowerShell cmdlets is no longer loaded by default. Use the LoadCmdletHelp parameter in the Connect-ExchangeOnline command so help for Exchange Online PowerShell cmdlets is available to the Get-Help cmdlet.
Fixed connection issues with app only authentication in Security & Compliance PowerShell.
Version 3.6.0
Get-VivaModuleFeature now returns information about the kinds of identities that the feature supports creating policies for (for example, users, groups, or the entire tenant).
Cmdlets for Viva feature access management now handle continuous access evaluation (CAE) claim challenges.
Added fix for compatibility issue with the Microsoft.Graph module.
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.
Version 3.5.0
New Get-VivaFeatureCategory cmdlet.
Added support for policy operations at the category level in Viva Feature Access Management (VFAM).
New IsFeatureEnabledByDefault property in the output of Get-VivaModuleFeaturePolicy. The value of this property shows the default enablement state for users in the tenant when no tenant or user/group policies were created.
Version 3.4.0
Bug fixes in Connect-ExchangeOnline, Get-EXORecipientPermission, and Get-EXOMailboxFolderPermission.
SkipLoadingCmdletHelp parameter on Connect-ExchangeOnline to support skip loading cmdlet help files.
Global variable EXO_LastExecutionStatus is available to check the status of the last cmdlet that was run.
Bug fixes in Connect-ExchangeOnline and Connect-IPPSSession.
IsUserControlEnabled parameter on Add-VivaModuleFeaturePolicy and Update-VivaModuleFeaturePolicy to support the enablement of user controls by policy for features that are onboarded to Viva feature access management.
Version 3.2.0
New cmdlets:
Get-DefaultTenantBriefingConfig and Set-DefaultTenantBriefingConfig.
Get-DefaultTenantMyAnalyticsFeatureConfig and Set-DefaultTenantMyAnalyticsFeatureConfig.
Get-VivaModuleFeature, Get-VivaModuleFeatureEnablement, Add-VivaModuleFeaturePolicy, Get-VivaModuleFeaturePolicy, Remove-VivaModuleFeaturePolicy, and Update-VivaModuleFeaturePolicy.
REST API connection support for Security & Compliance PowerShell.
ConnectionId parameter on Get-ConnectionInformation and Disconnect-ExchangeOnline:
Get connection information for specific REST API connections.
Selective disconnect for REST API connections.
SigningCertificate parameter on Connect-ExchangeOnline allows you to sign the format files (*.Format.ps1xml) or script module files (.psm1) in the temporary module that Connect-ExchangeOnline creates with a client certificate to use in all PowerShell execution policies.
Bug fixes in Connect-ExchangeOnline.
Version 3.1.0
AccessToken parameter available in Connect-ExchangeOnline.
Bug fixes in Connect-ExchangeOnline and Get-ConnectionInformation.
Bug fix in Connect-IPPSSession for connecting to Security & Compliance PowerShell using CertificateThumbprint.
Version 3.0.0 (Preview versions known as v2.0.6-PreviewX)
The SkipLoadingFormatData switch on the Connect-ExchangeOnline cmdlet for REST-based connections (version 2.0.6-Preview8 or later).
The DelegatedOrganization parameter works in the Connect-IPPSSession cmdlet as long as you also use the AzureADAuthorizationEndpointUri parameter in the command.
Certain cmdlets that used to prompt for confirmation in specific scenarios no longer do so. By default, the cmdlet runs to completion.
The format of the error returned from failed cmdlet execution is slightly modified. The exception now contains more data (for example, the exception type), and the FullyQualifiedErrorId doesn't contain the FailureCategory. The format of the error is subject to further modification.
Version 2.0.5
New Get-OwnerlessGroupPolicy and Set-OwnerlessGroupPolicy cmdlets to manage ownerless Microsoft 365 groups.
Note
Although the cmdlets are available in the module, the feature is only available to members of a Private Preview.
New Get-VivaInsightsSettings and Set-VivaInsightsSettings cmdlets to control user access to Headspace features in Viva Insights.
The module in PowerShell 7 supports browser-based single sign-on (SSO) and other sign in methods. For more information, see PowerShell 7 exclusive connection methods.
The Get-UserAnalyticsConfig and Set-UserAnalyticsConfig cmdlets were replaced by the Get-MyAnalyticsConfig and Set-MyAnalyticsConfig. Additionally, you can configure access at feature level. For more information, see Configure MyAnalytics.
Real-time policy and security enforcement in all user based authentication. Continuous Access Evaluation (CAE) is enabled in the module. Read more about CAE here.
The LastUserActionTime and LastInteractionTime properties are now available in the output of the Get-EXOMailboxStatistics cmdlet.
The interactive sign-in process now uses a more secure method to fetch access tokens using safe reply URLs.
Version 2.0.3
General availability of certificate based authentication (CBA), which enables using modern authentication in unattended scripting or background automation scenarios. The available certificate storage locations are:
Remote in the Azure Key Value (the Certificate) parameter. This option enhances security by fetching the certificate only at runtime.
Local in the CurrentUser or LocalMachine certificate store (the CertificateThumbprint parameter).
Connect to Exchange Online PowerShell and Security & Compliance PowerShell simultaneously in a single PowerShell window.
The new CommandName parameter allows you to specify and restrict the Exchange Online PowerShell cmdlets that are imported in a session. This option reduces the memory footprint for high usage PowerShell applications.
Get-EXOMailboxFolderPermission now supports ExternalDirectoryObjectID in the Identity parameter.
Optimized latency of the first V2 cmdlet call. Lab results show the first call latency has been reduced from 8 seconds to approximately 1 second. Actual results depend on the cmdlet result size and the tenant environment.
Version 1.0.1
General Availability (GA) version of the EXO V2 module. It's stable and ready for use in production environments.
Get-EXOMobileDeviceStatistics cmdlet now supports the Identity parameter.
Improved reliability of session auto-reconnect in certain cases where a script was running for ~50 minutes and threw a "Cmdlet not found" error due to a bug in auto-reconnect logic.
Fixed data-type issues of two commonly used "User" and "MailboxFolderUser" attributes for easy migration of scripts.
Enhanced support for filters as it now supports four more operators: EndsWith, Contains, Not and NotLike support. Check Filters in the Exchange Online PowerShell module for attributes that aren't supported in filters.
Version 0.4578.0
Added support for configuring the Briefing Email for your organization at the user level with Set-UserBriefingConfig and Get-UserBriefingConfig cmdlets.
Support for session cleanup using Disconnect-ExchangeOnline cmdlet. This cmdlet is the V2 equivalent of Get-PSSession | Remove-PSSession. In addition to cleaning up session object and local files, it also removes the access token from cache, which is used for authenticating against V2 cmdlets.
You can now use FolderId as an identity parameter in Get-EXOMailboxFolderPermission. You can get the FolderId value using Get-MailboxFolder. For example:
Get-MailboxFolderPermission -Identity <UPN>:<Folder-Path>Get-MailboxFolderPermission -Identity <UPN>:\<Folder-Id>
Improved reliability of Get-EXOMailboxStatistics as certain request routing errors that led to failures have been resolved.
Optimized memory usage when a session is created by re-using any existing module with a new session instead of creating a new one every time a session is imported.
Version 0.4368.1
Added support for Security & Compliance PowerShell cmdlets using the Connect-IPPSSession cmdlet.
Hiding the announcement banner is available using the ShowBanner switch (-ShowBanner:$false).
Terminate cmdlet execution on client exception.
Remote PowerShell contained various complex data types that were intentionally not supported in EXO cmdlets to improve performance. Differences in non-complex data types between remote PowerShell cmdlets and V2 cmdlets have been resolved to allow seamless migration of management scripts.
Version 0.3582.0
Support for prefix during session creation:
You can create only one session at a time that contains prefixed cmdlets.
EXO V2 cmdlets aren't prefixed because they already have the prefix EXO, so don't use EXO as a prefix.
Use EXO V2 cmdlets even if WinRM Basic Auth is disabled on client machine. Remote PowerShell connections require WinRM Basic Auth, and remote PowerShell cmdlets aren't available if Basic Auth is disabled in WinRM.
Identity parameter for V2 cmdlets now supports Name and Alias. Using Alias or Name slows down the performance of V2 cmdlets, so we don't recommend using them.
Fixed issue where the data type of attributes returned by V2 cmdlet was different from remote PowerShell cmdlets. We still have few attributes with differing data types, and we plan to handle them in coming months.
Fixed bug: Frequent sessions reconnect issue when Connect-ExchangeOnline was invoked with Credentials or UserPrincipalName
Version 0.3555.1
Fixed a bug where piped cmdlets were failing with the following error due to an authentication issue:
Cannot invoke the pipeline because the runspace isn't in the Opened state. Current state of the runspace is 'Closed'.
Version 0.3527.4
Updated Get-Help content.
Fixed an issue in Get-Help where the Online parameter was redirecting to a nonexistent page with error code 400.
Version 0.3527.3
Added support for managing Exchange for a different tenant using delegation flow.
Works in tandem with other PowerShell modules in a single PowerShell window.
Added support for positional parameters.
Date Time field now supports client locale.
Bug fix: PSCredential empty when passed during Connect-ExchangeOnline.
Bug fix: Client module error when filter contained $null.
Sessions created internal to EXO V2 Module now have names (naming pattern: ExchangeOnlineInternalSession_%SomeNumber%).
Bug fix: Remote PowerShell cmdlets intermittently failing due to time the difference between token expiry and the Session going idle.