Faster and more reliable Exchange Online Management using PowerShell V2 Cmdlets
Published Mar 04 2020 07:03 AM 26.6K Views

For more updates on this module, please see Announcing General Availability of the Exchange Online PowerShell v2 Cmdlets.

At Microsoft Ignite 2019, we announced new Exchange Online management cmdlets and showed how they can be used to perform fast and highly reliable data retrieval  operations. These cmdlets are generally 4-8 times faster and have proven to be highly reliable for bulk-retrieval scenarios. We have seen more than 50,000 total downloads of the V2 module available via PowerShellGallery and have seen around 11 million V2 cmdlets being executed in the past 30 days. Many large enterprises have already started using the new cmdlets in their production environment and we’re very proud of that.

The new EXO V2 module contains all the old Remote PowerShell cmdlets as well as (currently) 9 new V2 cmdlets. These 9 cmdlets use REST API to fetch data. This change alone makes them faster and highly reliable.

Since the new module is available on PowerShellGallery, it can be easily installed using the command line. Compared to the MFA PowerShell module, which required a Click-2-run installation, the new module is far better suited to automation scenarios.

The module is currently in Public Preview and will be released as “Generally Available” soon.

What’s new post Ignite?

Support for managing customer tenants using Delegated Authentication

The new module also supports CSP delegation for DAP (Delegated Admin Privileges) partners. Delegate admins can manage customer tenants by passing their customer tenant ID during Connect-ExchangeOnline

 

$cred = Get-Credential
$customerTenant = “contoso-electronics.onmicrosoft.com”
Connect-ExchangeOnline -DelegatedOrganization $customerTenant -Credential $cred

 

Read more on how to use it in MFA PowerShell module here

Identity is now a positional parameter and it supports name/alias

The initial release of V2 module didn’t support using name and alias as Identity parameter. This was a conscious call to provide better performance of cmdlets as resolution of name and alias was a costly operation. However, with the constant feedback from preview community, we learnt that a lot of scenarios require quick data access for a small set (most commonly 1) of mailbox using PowerShell interactively. And in those scenarios having support for positional parameter and using name alias brings a lot of convenience.

For example:

 

Get-ExoMailbox -Identity contosoadmin@fabrikam.com

 

…can now be written as:

 

Get-ExoMailbox contosoadmin

 

Assuming contosoadmin is the alias of user contosoadmin@fabrikam.com of course.

Improved error handling, reduced data type differences and many more bug fixes

The latest version of client module contains bug fixes across Get-Help, unwanted session kills, almost all the properties have same data-type across RPS and V2 cmdlets thus reducing script migration overhead. Also, the dateTime property now honors the client-side locale and shows time according to your local machine time zone.

Please read the detailed release notes here

How do you get the best out of V2 cmdlets?

Use PropertySets and Properties parameters

Traditionally, RPS Cmdlets returned all mailbox properties in the output object. Most of these properties were not usually required but were part of the returned object which caused performance degradation.
In the new module we have bucketized certain related set of properties and called them “PropertySets”. These PropertySets are simply buckets of 2 of more Properties. We have exposed 2 new parameters in EXO Cmdlets: Properties and PropertySets.

  • PropertySets – it accepts one or more (in comma separated form) names of the properties buckets i.e. PropertySets. The following example will return all the properties mentioned in Minimum, Archive & Custom:

 

Get-ExoMailbox -PropertySets Archive, Custom

 

  • Properties – it accepts one or more (in comma separated form) name of the output property

 

Get-ExoMailbox -Properties LitigationHoldEnabled, AuditEnabled

 

You can specify PropertySets as well as Properties at the same time:

 

Get-ExoMailbox -Properties IsMailboxEnabled, SamAccountName -PropertySets Delivery
Get-ExoCASMailbox -Properties EwsEnabled, MAPIBlockOutlookNonCachedMode -PropertySets ActiveSync 

 

We have also introduced a new concept call “Minset” which is a bare minimum set of properties. If you don’t specify any PropertySets, you will get the bare minimum properties every time. If you specify a PropertySet while invoking a cmdlet, you will only get the “Properties” specified in the PropertySets parameter and you won’t get the properties listed in “Minimum” bucket.

Read more about property sets here.

Use Piping to get multi-threading benefit

Pipelines act like a series of connected segments of pipe. Items moving along the pipeline pass through each segment.  The V2 module invokes multiple threads on the client machine to parallelize execution and retrieval and thus provides a better performance in data retrieval.

V2 Cmdlets 1.pngIt can be clearly seen that for-looping took 900 seconds to get Mailbox Statistics for 100 mailboxes while it only took 48 seconds for the same operation using pipe operator. Nice!

What's Next?

Support for PowerShell Core

The V2 module works only on Windows PowerShell version 5.0 or lower. It doesn’t work on non-Windows Operating Systems i.e. Linux, Mac.

We plan to add the support for PowerShell 6 and 7 in the new V2 module so that it works seamlessly on Linux, Mac and windows.

Support for Automation using Certificate Based Authentication

Exchange Online management didn’t have official support for app-only scenarios i.e. background jobs authentication, scheduling etc. Currently, we are working on support app-only authentication using Certificates and Service Principal objects available in AzureAD. This is really important work and will help get you off Basic Authentication in Exchange Online, which as we hope you know, is being retired.

Frequently asked questions

How to handle the Windows 10 PowerShellGet Error?

For PowerShell version 5.1 which got shipped with Windows, a known issue causes an error during a module installation from PowerShell Gallery.The error message is shown below and the installation doesn’t succeed when this warning is shown:

Warning: The specified module ‘ExchangeOnlineManagement’ with PowerShellGetFormatVersion ‘2.0’ is not supported by the current version of PowerShellGet.

The current workaround is to forcefully install PowerShellGet using the below cmdlet:

 

Install-Module PowerShellGet -Scope AllUsers -Repository PSGallery -Force -AllowClobber

 

You will then need to re-load the PowerShell session; you can do this with the command:

 

PowerShell

 

You should then be able to successfully use the latest version of PowerShellGet

 

Install-Module -Name ExchangeOnlineManagement -Verbose -Scope AllUsers -Force

 

In case above steps doesn’t work for you, please read this on how to install the PowerShellGallery module manually.

Basic Auth still needs to be enabled on your client machine

The new PowerShell V2 module uses Modern Auth to establish connection for enabling all the 9 (as of this writing) REST-based V2 Cmdlets. In addition to V2 cmdlets, it also allows you to access 700+ of the older Remote PowerShell Cmdlets which requires a Remote PowerShell session to be established. Establishing an RPS session on Windows machine require WinRM BasicAuth to be enabled on the client machine even though it used Modern Auth mechanism to authenticate. The WinRM Basic Auth pipeline is essentially used for transporting Modern Auth tokens. If WinRM Basic Auth is disabled on the client machine, the new V2 cmdlets will continue to work (but the older RPS cmdlets will not)

We really hope you enjoy using the new Exchange Online V2 module, and we look forward to your feedback as we continue to improve them.

The Exchange Admin Team

25 Comments

PowerShell 7 is now out, so no excuse not to support it :) And yeah, automation! Keep up the good work, I like this monthly release cadence.

Microsoft

@Vasil Michev Support for PS 7/Core in an active work in progress and will be available for preview soon.

Brass Contributor

@navgupta looking forward for the PowerShell 7 support :) ... i'm currently using with the -UseWindowsPowerShell switch to get around the limitation today, although it still doesnt import the older cmdlets Get-Mailbox etc.

 

a question around the v2 module though, when will we be able to use Get-EXORecipient -Filter against the company value ... today i have a lot of scripts which use Get-Recipient -Filter {Company -EQ 'XXX'} but this doesnt translate to Get-EXORecipient. is this because the underlying graph doesnt have a odata filter for the Company attribute?

Brass Contributor

Filter is absolutely critical to handling large tenants. Not only to allow selection of groups of users, but is used in conjunction with a “tracer” property update so you know which accounts have been processed when you have to restart the process due failures. 
Even with robust cloud command, account updates, such as adjusting audit settings, fail 2/3rds of the time when running processes that span days and sometimes weeks. (At least with about 165k of mailboxes)

Copper Contributor

Is there documentation on how this new module connects out to the Internet?  I installed it on a Windows 2016 server where we have tools installed, but when trying to connect it fails with WinRM errors.  WinRM is running and does allow basic auth.  I suspect the proxy that outbound traffic is directed through is causing issues as this works from my Windows 10 laptop that doesn't use the datacenter proxy.

Microsoft

@JWare - The EXO V2 Module uses AzureAD user based authentication for the new Cmdlets. At the same time, it uses WinRM to establish remote session for running older RPS Cmdlets.

 

Please share your error in below format as described in documentation here - https://aka.ms/exops-docs

Microsoft

@UW_Scott - We are totally aligned with your thought here. Server side filters will be available in upcoming releases of the module.

 

However, you can always use filters on client side using 'Where-Object" as the new Cmdlets retrieve data significantly faster than their RPS counterparts.

 

 

Microsoft

@DevOpsMaverick - You guessed it right. A lot of filterable properties are not available in odata thus making it harder to support filters on those.

 

Since, Get-EXORecipient is significantly faster than Get-Recipent, how about fetching the company value property for all recipients and using a client side filtering using "Where-Object" clause? 

Brass Contributor

Could you please confirm if the new EXO V2 module supports the national clouds, like Office 365 operated by 21Vianet in China?

Microsoft

@JWare : Proxies can be annoying.

This usually helps to resolve that:

 

$options New-PSSessionOption -ProxyAccessType IEConfig
Connect-ExchangeOnline -PSSessionOption $options

 

For the rest calls, it may be necessary to set up the default proxy settings for the .NET side of things before connecting:

 

[System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebProxy]::new('<proxyurl>:<proxyport>')

[System.Net.WebRequest]::DefaultWebProxy.UseDefaultCredentials = $true

[System.Net.WebRequest]::DefaultWebProxy.BypassProxyOnLocal = $true

Steel Contributor

Hello, I've reported this to the feedback email address as well, but the -Identity parameter fixes outlined in this post - seem to have only been applied to Get-EXOMailbox.

 

Get-EXO<everythingelse> still can only accept the Azure AD ObjectId/UserPrincipalName, or the EXO ExternalDirectoryObjectId/UserPrincipalName.

Get-EXOMailboxFolderPermission erroneously demands that a backslash comes after the colon in Identity.  However, when using the FolderId, rather than the FolderPath, the backslash shouldn't be there.

Steel Contributor

Regarding the progress around Prefix, I think it would be nice to also have CommandName and FormatTypeName available as well.  If we only need to run 1 or 2 cmdlets, it's way faster/better to only download those 2 cmdlets (and optionally their format type data).  This idea is in the name of efficiency both for Microsoft and the customers.

Brass Contributor

Any movement on Server Side filters or updates on levels of available filterable properties with an OData query ...?

Microsoft

@DevOpsMaverick - Server side filters are a work in progress. A few wild card operators which ODATA doesn't support will not be available in the EXO cmdlets. Rest will be available. 

Brass Contributor

I'm loving the new module so far, it's infinitely easier to script the install, maintenance, and connection, and I can't wait for cert based auth.

However, what is the plan for Exchange Online Protection? It was included in the V1 module, so are it's commands going to be made available in the V2 module as well, or is there another module in the works specifically for it?

Microsoft

Exchange Online Protection cmdlets are available in the latest version of EXO PowerShell V2 module published on 30th March.

Check https://aka.ms/exops-v2

Brass Contributor

Great timing! I just updated and everything seems to be working well so far. Cheers!

Brass Contributor

This is awesome. We have few automations and been looking to  use CBA to authenticate. Is there any TAP program we can sign up for to help validate any scenarios.

Copper Contributor

I have a script in which I need to get the FolderPath for the Calender folder in each mailbox, for which I use Get-MailboxFolderStatistics. To test the performance I measured the time doing Get-MailboxFolderStatistics and Get-EXOMailboxFolderStatistics for all mailboxes. With the new and supposedly faster cmdlet this took 4x longer! Only when I ran the test a second time was it slightly faster (like 25%) than the old cmdlet, because it apparently uses caching.


If we cannot assume that the new cmdlets are at least not slower than the old ones, then I don't see the point in switching to them. So far I'm not impressed.

 

I also noticed that Get-Help -Online will open the wrong URL (it uses https://docs.microsoft.com/en-us/powershell/module/exchange/exchange-ps-v2-module/ when it should be https://docs.microsoft.com/en-us/powershell/module/exchange/powershell-v2-module/)

 

Microsoft

Hi @Gerard 

 

This is not expected. We would like to debug further and see why Get-EXOMailboxFolderStatistics is slower for you. We have not heard any feedback for it's slowness. Can you share the details at the email which gets printed when you do Connect-ExchangeOnline ?

 

We will take it up from there for further investigation.

 

Thanks

Exchange Online IT Admin Experiences Team

Brass Contributor

When can we expect certificate based auth support? Unfortunately we have lot of automation and we cannot leverage this module until CBA is supported.

Happy to help with any testing or validation.

Steel Contributor

@Gerard I forget where it is documented but the first MS Graph based cmdlet execution is known to take a while as it sets up the MS Graph authentication.  The second and later commands are when you see the enhanced performance.

 

Where I've noticed the dramatic speed increase is with large large sets of data where it is now saving me many hours of script processing time.

Copper Contributor

Hello Exchange team, 

 

The Microsoft code signing certificate you used for signing Exchange Online PowerShell v2 module has expired on May 2nd 2020. 

 

Kind regards, 

 

Dejan Foro 

dejan.foro@exchangemaster.ch 

Exchangemaster GmbH 

www.exchangemaster.ch

Bronze Contributor

Is it me only, who need "get-mailuser" and all related cmdlet, but is unable to find them from new module (0.4578.0)? 

 

Edit: :flushed:

Working again.

Brass Contributor

Any news on the PS7 support front?

Version history
Last update:
‎Jun 03 2020 11:15 AM
Updated by: