Skip to content

/cheatsheets/exchange-online/exchange-online-powershell-cheat-sheet

Exchange Online PowerShell cheat sheet (ExchangeOnlineManagement V3)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
Exchange Online PowerShell
versions
ExchangeOnlineManagement 3.10.1
os
windows, linux, macos

Commands for the ExchangeOnlineManagement module (EXO V3), grouped by task. Every cmdlet except the connection cmdlets needs Connect-ExchangeOnline first; replace the example addresses with yours.

Install and connect

powershell
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
Get-ConnectionInformation          # open connections
Disconnect-ExchangeOnline -Confirm:$false

The module itself contains only the connection cmdlets and nine fast Get-EXO* cmdlets; all other Exchange cmdlets are added by the connection. The nine Get-EXO cmdlets, listed offline from module 3.10.1:

powershell
Import-Module ExchangeOnlineManagement
Get-Command -Module ExchangeOnlineManagement -Name 'Get-EXO*' | Sort-Object Name | ForEach-Object Name

Output

Get-EXOCasMailbox
Get-EXOMailbox
Get-EXOMailboxFolderPermission
Get-EXOMailboxFolderStatistics
Get-EXOMailboxPermission
Get-EXOMailboxStatistics
Get-EXOMobileDeviceStatistics
Get-EXORecipient
Get-EXORecipientPermission

Find mailboxes and recipients

CommandTask
Get-EXOMailbox -ResultSize UnlimitedAll mailboxes (fast)
Get-EXOMailbox -RecipientTypeDetails SharedMailbox -ResultSize UnlimitedShared mailboxes only
Get-EXORecipient -Identity user@contoso.comAny recipient by address
Get-EXORecipient -Filter "EmailAddresses -eq 'smtp:user@contoso.com'"Who owns an address
Get-EXOMailboxStatistics -Identity user@contoso.comMailbox size
Get-Mailbox -Identity user@contoso.com | Format-ListAll properties of one mailbox

Permissions

CommandTask
Add-MailboxPermission -Identity sales@contoso.com -User anna@contoso.com -AccessRights FullAccess -InheritanceType AllFull Access
Add-RecipientPermission -Identity sales@contoso.com -AccessRights SendAs -Trustee anna@contoso.com -Confirm:$falseSend As
Set-Mailbox -Identity sales@contoso.com -GrantSendOnBehalfTo @{Add="anna@contoso.com"}Send on Behalf
Get-EXOMailboxPermission -Identity sales@contoso.comList Full Access
Get-EXORecipientPermission -Identity sales@contoso.comList Send As
Add-MailboxFolderPermission -Identity anna@contoso.com:\Calendar -User bob@contoso.com -AccessRights EditorCalendar permission

Mailbox settings

CommandTask
Set-Mailbox -Identity anna@contoso.com -Type SharedConvert to shared
Set-Mailbox -Identity anna@contoso.com -ForwardingSmtpAddress smtp:anna@fabrikam.com -DeliverToMailboxAndForward $trueForward and keep a copy
Set-Mailbox -Identity anna@contoso.com -ForwardingSmtpAddress $nullRemove forwarding
Set-Mailbox -Identity anna@contoso.com -EmailAddresses @{Add="smtp:a.smith@contoso.com"}Add an alias
Set-MailboxAutoReplyConfiguration -Identity anna@contoso.com -AutoReplyState Enabled -InternalMessage "Away" -ExternalMessage "Away"Out of office
Set-Mailbox -Identity anna@contoso.com -HiddenFromAddressListsEnabled $trueHide from address lists

Distribution groups

CommandTask
New-DistributionGroup -Name "ITDepartment" -Members chris@contoso.com,laura@contoso.comCreate a distribution list
New-DistributionGroup -Name "Managers" -Type SecurityCreate a mail-enabled security group
Add-DistributionGroupMember -Identity "Staff" -Member john@contoso.comAdd a member
Remove-DistributionGroupMember -Identity "Staff" -Member john@contoso.com -Confirm:$falseRemove a member
Get-DistributionGroupMember -Identity "Staff" -ResultSize UnlimitedList members
Get-UnifiedGroupLinks -Identity "Sales" -LinkType MembersMicrosoft 365 group members

-Type accepts Distribution (default, cannot be used for permissions) and Security (mail-enabled security group, can hold permissions).

Mail flow

CommandTask
Get-MessageTraceV2 -SenderAddress anna@contoso.com -StartDate (Get-Date).AddDays(-2) -EndDate (Get-Date)Trace by sender
Get-MessageTraceV2 -RecipientAddress anna@contoso.com -Status FailedFailed messages to a recipient
Get-MessageTraceDetailV2 -MessageTraceId GUID -RecipientAddress anna@contoso.comEvents of one message

How to read this cheat sheet

Each table pairs a command you can paste with the task it performs. Three rules explain most surprises:

  • Two kinds of cmdlets. The Get-EXO* cmdlets ship inside the module and exist as soon as you import it; everything else (Get-Mailbox, Set-Mailbox, New-DistributionGroup, Get-MessageTraceV2) is created by Connect-ExchangeOnline for the session. Before you connect, the first kind fails with You must call Connect-ExchangeOnline and the second kind is "not recognized".
  • Result size. Most Get- cmdlets stop at 1000 objects. Add -ResultSize Unlimited whenever you report on a whole tenant, or the export silently misses objects.
  • Fast versus complete. Get-EXOMailbox returns a minimal property set unless you add -Properties or -PropertySets; Get-Mailbox returns every property but is slower. The comparison page lists the differences.

Permissions you need

Exchange Online uses role-based access control. Reading recipients needs a role such as View-Only Recipients; changing mailboxes, permissions and groups needs Recipient Management or Organization Management; message trace needs a role that includes the trace cmdlets. Role changes apply to new sessions only, so run Disconnect-ExchangeOnline and connect again after an administrator assigns a role. For unattended scripts, use certificate-based app-only authentication instead of a user account.

Errors you will meet

MessageWhat it means
You must call Connect-ExchangeOnline before calling any other cmdlet.A Get-EXO cmdlet ran before the session was opened; connect first.
The term 'Get-Mailbox' is not recognizedNo connection yet, or your roles do not include the cmdlet.
The operation couldn't be performed because object '...' couldn't be foundThe identity does not match any recipient; check the address or use the GUID.
The proxy address "SMTP:..." is already being used by the proxy addresses or LegacyExchangeDNAnother recipient already owns the alias you tried to add.

Details and fixes: object couldn't be found, proxy address already being used, Get-Mailbox not recognized.

FAQ

Why does Get-Mailbox work for a colleague but is not recognized for me?

Connect-ExchangeOnline imports only the cmdlets your RBAC roles allow. If your account lacks a role that contains Get-Mailbox or Set-Mailbox, the cmdlet is simply not created in your session.

Should I use Get-EXOMailbox or Get-Mailbox in scripts?

Use Get-EXOMailbox for bulk reads: it is part of the module and returns only the property sets you request. Use Get-Mailbox when you need a property or parameter that the EXO cmdlet does not expose.

Does the module work in PowerShell 7 on Linux and macOS?

Yes. ExchangeOnlineManagement 3.x runs in Windows PowerShell 5.1 and in PowerShell 7 on Windows, Linux and macOS, because V3 uses REST instead of remote PowerShell sessions.

Sources