Tuning PowerShell for Office 365 Group Membership

Making PowerShell Faster with Office 365 Groups

A recent Practical365.com article by Steve Goodman covering how to export the membership of an Office 365 group to a CSV file caused me to test a recommendation we make in Chapter 14 of the Office 365 for IT Pros eBook.

The recommendation is to select properties that you want to process when fetching a set of objects like mailboxes or groups. The idea is that this approach results in a set of filtered objects instead of needing an extra step to use ForEach-Object to loop through the set to fetch properties.

Exporting Group Membership

In this instance, Steve’s script calls the Get-UnifiedGroupLinks cmdlet to get the membership of a group. He then loops through the membership to extract the primary SMTP address for each member. Nice and simple.

As it happens, Get-UnifiedGroupLinks is a “heavy” cmdlet because it returns the same set of properties as a call to Get-Mailbox (for a tenant user) or Get-MailUser (for a guest member). If you examine the set of properties returned, you’ll see how many they are. For example:

$Members = Get-UnifiedGroupLinks -Identity ExchangeGoms -LinkType Member
$Members[0] | Format-List

Returning to my theory that we can speed things up by selecting the required properties by piping the output of a cmdlet to Select-Object, we can use PowerShell’s Measure-Command cmdlet to test if it is any faster.

Here’s the code from the article as fed through Measure-Command:

Measure-Command { $Members = Get-UnifiedGroupLinks -Identity ExchangeGoms -LinkType Members -ResultSize Unlimited
    $MembersSMTP=@()
    foreach ($Member in $Members) {$MembersSMTP+=$Member.PrimarySmtpAddress}}

Seconds           : 0
Milliseconds      : 858
Ticks             : 8586323
TotalSeconds      : 0.8586323
TotalMilliseconds : 858.6323

Not too bad. Now let’s try the alternative. As you can see, this result is faster.

Measure-Command {$MembersSMTP = (Get-UnifiedGroupLinks -Identity ExchangeGoms -LinkType Members -ResultSize Unlimited | Select PrimarySmtpAddress)}

Seconds           : 0
Milliseconds      : 522
Ticks             : 5222026
TotalSeconds      : 0.5222026
TotalMilliseconds : 522.2026

Extended Testing

I used an Office 365 group with 51 members to test both approaches. The results of a single run (above) shows that avoiding a loop is faster and I suspect that the impact is greater as group membership grows. However, it’s important to recognize that demand on the Exchange Online server that handles the request can vary the results of any PowerShell command, so I ran both commands twenty times to see if the advantage is kept over an extended series. The results showed that using a ForEach loop to extract properties is about 9% slower than extracting with Select.

Warning! Your mileage may vary depending on the number of members in the group and the type of members (users versus guests). Even so, the exercise proves that it is possible to improve PowerShell performance by paying attention to what you ask Office 365 to return as a response to a command. Whether or not the extra performance will make any difference or be noticeable is entirely a different matter.


For more information about using PowerShell to manage Office 365 Groups and Teams, see Chapter 14 of the Office 365 for IT Pros eBook.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.