Running PowerShell commands against a large group of mailboxes or returning large data returns

Scenario: While attempting to run Exchange Online PowerShell commands against a large group of mailboxes and/or returning large datasets, you may run into mico delays or other errors once you breach any number of throttles that Microsoft Online imposes against your PowerShell session. Although throttles protect Microsoft Online for good reason, your still left with the question “WHY ME?” and how do we get around these strict restrictions.

Solutions: There’s a few ways to execute commands in Exchange Online PowerShell, but each have their own advantages and disadvantages. Below are a few examples with running the command: get-mobiledevicestastics which is naturally heavy in processing and subject to breaching throttles.

Standard Command – This may work if you only have a small number of mailboxes in your environment. Its quick, but also dangerous.
$AllMailboxes.alias | Get-mobiledevicestatistics -mailbox $_

ForEach with a Mini-Sleep – This command will help with some of the throttling, its not difficult to execute by implementing a 2-command loop and will help with the recharge rate for how many commands you are allowed to execute within a time period.

$AllMailboxes.alias | %{ Get-mobiledevicestatistics -mailbox $_; Start-Sleep -milliseconds 500}
$AllMailboxes.alias | ForEach { Get-mobiledevicestatistics -mailbox $_; Start-Sleep -milliseconds 500}

Invoke-Command to help with Large Data Return – Invoke with Select-Object forces the O365 servers run the command and limits the data returned. This takes your local client out of the loop helping to ease local client throttling. HOWEVER invoke command doesn’t allow complex PowerShell commands either.

Invoke-Command -session (Get-Pssession) -scriptblock {Get-mobiledevicestatistics -mailbox $_ | select-object identity, Device*,LastSuccessSync}
Invoke-Command -session (Get-Pssession) -scriptblock {Get-Mailbox -resultsize unlimited | select-object -property Displayname,Identity,PrimarySMTPAddress}

Microsoft Module: RobustCloudCommand – Microsoft created a module that can be used, originally it used to be a script. The module is designed to stay under the throttling limitations imposed by Microsoft. The module keeps an eye on the amount of commands issued, the amount of time or data collected, throttling errors, and so on. The module will tear down and rebuild the PowerShell session when needed and pickup where the script left off. AND one of the coolest things is that it supports Modern Auth and will renew your OAUTH tokens automatically. Let those big scripts fly! The only issue I see is that its limited in complex PowerShell commands. However if you want to run a single command, such as adding a BlockEverything Authentication Policy for every single one my theoretical 400K users, the workhorse below will do the trick

Install-Module -Name RobustCloudCommand #

$users = Import-csv C:\temp\AllMailboxes.csv

Start-RobustCloudCommand -recipients $Users -logfile C:\temp\out.log -ScriptBlock {Get-user $input.userprincipalname -AuthenticationPolicy BlockEverything}


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: