Why You Should Use the Exchange Online PowerShell Module

Microsoft recently released the EXOv2 (Exchange Online Version 2) cmdlets for automating and managing Exchange Online. You as an Office 365 administrator probably rely on them every day and they are essential indeed.

In this article, we will explore why you should use the EXOv2 PowerShell module and how it can benefit you as an Office 365 administrator.

Prerequisites

To follow along in this article you will need PowerShell 5.1 and access to an Office 365 account that has administrative access to Exchange Online.

Easy install

The former version of the Exchange Online PowerShell cmdlets was not a PowerShell module but a remote session that you imported through HTTPS. This meant that every other admin created their own function for connecting to Exchange Online since many didn’t want to type in that long URL when they ran Connect-PSSession.

But the new EXOv2 cmdlets (as you can see in the title) are in a module! And it’s available in the PowerShell Gallery.

To install the module you enter the following:

​

​
This means that everyone will get a uniform way of connecting to Exchange Online with PowerShell and makes script sharing among colleagues a lot easier.

Modern Authentication

The major security feature of the EXOv2 module is that it supports Modern Authentication! Modern Authentication is a web-based authentication flow and that means that you can use any MFA method that you want (as long as it’s compatible with your AzureAD or connected IdP). This is a major lift when it comes to security since many admins had MFA disabled just because of this lacking feature in the old cmdlets. Future releases of EXOv2 (currently in limited preview) will let you authenticate with certificates. That’s great when it comes to your automated scripts and tasks in exchange online!

Improved speed

The most noticeable difference with the EXOv2 module is that it’s so much faster. Tasks that took hours (or even days for larger environments) are now shortened dramatically. One of the key contributors to this is probably the implementation of Multithreading and PropertySets. The PropertySets implementation means that you can set one or several sets of properties that you want the commands to return. For example, if you run the Get-EXOMailbox without specifying one or several PropertySets it will only return 15 properties:

​

​
But if you specify the "All" property sets containing all the properties you will get a completely different result:
​

​
225 different properties were returned! But what is the impact on speed when using PropertySets? Well, the harsh truth is that it is actually slower (currently) to fetch all properties with the Get-EXOMailbox command compared to the old Get-Mailbox command. Let's test it out by calculating the average time of running Get-Mailbox compared to GetEXOMailbox 10 times:
​

​
The old Get-Mailbox command completes on an average time of 0.74 seconds. Now let's try it out with the new Get-EXOMailbox command:
​

​
Fetching all the properties takes more than twice as long with the new EXOv2 command compared to the legacy Get-Mailbox. But this is where the power of the PropertySets comes into play that lets you fetch only the properties that you need for a given task:
​

​
And you have now reduced the time it took to fetch all mailboxes to 0.3 seconds. That's more than twice as fast as the old Get-Mailbox command! Now let's have a look at how to make things go even faster when you are using filters.

Improved filters

The new EXOv2 module has improved the server-side filtering and is generally even faster than performing the filtering on the client. You can see this for yourself by comparing the 2 different methods using the code below that fetches all users with a UserPrincipalName ending with @example.com:

$ClientSide = 1..10 | Foreach {
    Measure-Command {
        Get-EXOMailbox | Where-Object  {$_.UserPrincipalName -like '*@example.com'}
    }
} | Measure-Object -Property TotalSeconds -Average

$ServerSide = 1..10 | Foreach {
    Measure-Command {
        Get-EXOMailbox -Filter "UserPrincipalName -like '*@example.com'"
    }
} | Measure-Object -Property TotalSeconds -Average

Write-Output "Client-side filtering took on average $($ClientSide.Average) seconds"
Write-Output "Server-side filtering took on average $($ServerSide.Average) seconds"

This will run Get-EXOMailbox 10 times with server-side filter and 10 times with client-side filtering using Where-Object.

With the filters used the server-side filtering is around 5-10% faster on average compared to using client-side filtering. But the noticeable difference between client and server-side filtering is even greater than that if you add more conditions.

In the following example below it filters on both UserPrincipalName ending in @example.com and all users with a DisplayName starting with ‘A’:

$ClientSide = 1..10 | Foreach {
    Measure-Command {
        Get-EXOMailbox | Where-Object  {$_.UserPrincipalName -like '*@example.com' -and $_.DisplayName -like "A*"}
    }
} | Measure-Object -Property TotalSeconds -Average

$ServerSide = 1..10 | Foreach {
    Measure-Command {
        Get-EXOMailbox -Filter "UserPrincipalName -like '*@example.com' -and DisplayName -like 'A*'"
    }
} | Measure-Object -Property TotalSeconds -Average

Write-Output "Client-side filtering took on average $($ClientSide.Average) seconds"
Write-Output "Server-side filtering took on average $($ServerSide.Average) seconds"

The performance gain with using server-side filtering here is even greater: 65% on average!

Historically with the legacy commands it’s been the complete opposite, where the greatest performance gains were made by filtering client-side.

Using the old commands

A lot of the commands that you use daily (especially for write operations) still don’t have an EXO equivalent. Luckily they are automatically imported when you use the Connect-ExchangeOnline command.

This means that you with the EXOv2 module also gain the security benefits from Modern Authentication for the old commands like Get-Mailbox or Set-Mailbox. Not only that but you also gain a uniform way of connecting to Exchange Online even for your old scripts (with minor modifications) as you will learn about next.

Converting old scripts

There are in most cases only 3 things that you need to do so that your old scripts can utilize the EXOv2 commands: Changing the way it connects to Exchange Online, replace the command with its EXO-equivalent and identifying the property sets that you need to add.

Let’s explore some examples starting out with replacing the authentication:

Replacing the way you connect to Exchange Online

This may be enough for most of your scripts if you don’t mind losing the performance benefits gained with the EXOv2 commands. You will still gain the advantages of being able to use MFA and in the future certificate authentication.

In most scripts the old way of connecting to Exchange Online looks similar to this:

​

​
To convert this to the Exchange Online V2 method just replace it with:
​

​
It is as easy as that! You will still get a password prompt but in the form of a web page instead of the traditional credential window. Now let's have a look at how to modify some old code to use the Get-EXOMailbox command.

Replacing the commands

To gain the most out of the new EXOv2 module and make your scripts faster you need to change the way some of your commands fetch information from Exchange Online to its EXO equivalent. The line of code below shows how to fetch all users with auditing enabled with the old method:

​

​
Now to convert this in the proper way with its new equivalent Get-EXOMailbox you need to identify the property sets that you want information from and move the filtering to the server-side. In this case, the only information needed is about auditing so the property set that you need to specify is

Audit:

​

​
You have now done so that the command only returns the properties that it needs and set the filtering to server-side which as you have tested out earlier is a lot faster than performing it client-side now that you utilize the EXOv2 commands.

Summary

While it still lacks some features compared to the legacy commands, especially considering performing write operations it’s the best way to make your old Exchange Online scripts run faster. The performance gains that you get utilizing EXOv2 is big by only adding minor modifications to your scripts. And don’t forget that you still get full backward compatibility since the EXOv2 module imports the old commands into PowerShell, but with Modern Authentication enabled! Hopefully, this article gave you some insight into why you should start using the Exchange Online Version 2 module and how you could get started.

Related Article: