Get-Mailbox Versus Get-ExoMailbox
Modernized Get-Mailbox Cmdlet Versus REST Get-ExoMailbox Cmdlet
In November 2019, Microsoft introduced a set of REST-based cmdlets designed to improve the performance and stability of the most frequently used PowerShell actions conducted against Exchange Online. The new set didn’t use Remote PowerShell and incorporated functionality like pagination (like Graph API requests). Given its usage in many scenarios, the Get-ExoMailbox cmdlet is possibly the poster child for the REST cmdlets. Many tests were run, usually successfully, to validate its performance advantages over the older Get-Mailbox cmdlet.
Get-Mailbox Still in Active Use
Five years on, I still see people use Get-Mailbox in their scripts. I was recently quizzed about the enduring nature of the older cmdlet. It’s a good question. Despite my advice, many chose to leave Get-Mailbox untouched in their scripts on the basis that if something isn’t broken it shouldn’t be touched. Get-ExoMailbox behaves differently, especially in how it fetches mailbox properties. In a nutshell, Get-ExoMailbox fetches just fifteen of the hundreds of available mailbox properties, so if you want a property like InPlaceHolds or ArchiveStatus, you must request them:
[array]$Mbx = Get-ExoMailbox -Properties Office, InPlaceHolds, ArchiveStatus
It’s all too easy to forget to request a property. I can appreciate that perspective because I’ve fallen into the unrequested property hole myself.
Another reason why people stick with Get-Mailbox is that Microsoft has modernized the older cmdlets to remove dependencies like basic authentication and remote PowerShell. I’ve heard the feeling expressed that if Microsoft puts time and effort into upgrading a cmdlet, it must be a good sign that the cmdlet can safely be used. And yes, Get-Mailbox is very safe to use.
The question then is when to use Get-Mailbox and when to opt for its turbo-charged version? I propose a simple guideline:
When you’re working interactively with less than five mailboxes, use Get-Mailbox. The cmdlet will fetch all available mailbox properties, but that’s OK because relatively few objects are involved. In addition, requests don’t need to page to find more data and the chances of time outs or other known problems are small when fetching a small number of mailboxes.
Anytime else, use Get-ExoMailbox. That means all scripts and Azure Automation runbooks should use Get-ExoMailbox. Scripts should include the best possible code and that means using the best possible cmdlets. The issue with requesting the correct set of properties shouldn’t occur because the testing of the script will highlight any problems in this area.
The same rule of thumb applies to the other REST cmdlets like Get-ExoMailboxStatistics, Get-ExoMailboxFolderStatistics, and so on. I have a lingering suspicion that Microsoft will dedicate more tender loving care to the REST cmdlets than their older counterparts. It’s probably not true, but stranger things have happened.
The Importance of Server-Side Filtering When Fetching Mailboxes
While I’m at it, let me advance another golden rule for use with either Get-Mailbox or Get-ExoMailbox: never use a client-side filter when a server-side filter is available. The reason is that a server-side filter is always faster than applying a client-side filter after retrieving all possible matching data over the network.
I review many articles and it’s surprising when a code example is submitted that abuses the server-side principle. For example, this server-side filtered command:
[array]$MBx = Get-ExoMailbox -filter {Office -eq ‘New York’} -Properties Office
is much faster than:
[array]$Mbx = Get-ExoMailbox -Properties Office -ResultSize 1000 | Where-Object {$_.Office -eq ‘New York’}
The exact performance advantage depends on the number of objects that are retrieved, but I have never seen a case when a client-side filter wins. Use the Measure-Command cmdlet to measure the speed advantage by running commands against mailboxes. This article has more information about using filters with Get-ExoMailbox.
A PowerShell Principle
The principle of using server-side filters extends anywhere PowerShell fetches data from a server, including using Microsoft Graph PowerShell SDK cmdlets. If you see the Where-Object cmdlet being used to extract a set of objects from a larger set, ask if the larger set could have been reduced with a server-side filter. In many cases, it can, and if a server-side filter can be applied, your scripts will run faster, no matter if you use Get-Mailbox or Get-ExoMailbox (but use the latter).
Learn how to exploit the data available to Microsoft 365 tenant administrators through the Office 365 for IT Pros eBook. We love figuring out how things work.