Exchange Online Administration

Table of Contents


Below are some common Exchange Online administrative tasks requiring PowerShell to get the job done. Microsoft as of January 2020 encouraged the adoption of the new Exchange Online v2 cmdlets, or abbreviated as EXO v2, for admin tasks.

On a slightly separate topic, I would recommend limiting your administrator account the required privileges and for limited periods; a great way to implement this is via Privileged Identity Management (PIM) that allows admins activate an eligible role(s) which then require written justification for an approver to grant their temporary privilege. This feature is available as part on an Azure AD Premium P2 license.
An alternative to PIM is to delegate a privileged role to fewer administrators or have create discrete admin account per administrator that is scoped to a specific role, ie:; this can be cumbersome to manage and could impose another risk if not secured properly. I would strongly avoid having highly privileged shared admin account as this limits any audit trail for when things go wrong.

PowerShell Modules for Exchange Online

To download the latest Exchange Online PowerShell modules: 


Import-Module ExchangeOnlineManagement; Get-Module ExchangeOnlineManagement

To update the Exchange Online Modules:

Update-Module -Name ExchangeOnlineManagement

In this example, Bob Barker requires Alice Jones to have ‘Editor’ delegation: 

Add-MailboxFolderPermission -Identity\Calendar -User -AccessRights Editor

Now Bob Barker requires Alice Jones to only have ‘Reader’ delegation:

Add-MailboxFolderPermission –Identity\calendar -User -AccessRights Reviewer 

Bob Barker requests to have Alice Jones’ delegation rights to his calendar removed:

Remove-MailboxFolderPermission -Identity\Calendar -User 

Assuming no one as access Bob's calendar while he's on leave, we need to clear a meeting room booking:

Remove-CalendarEvents -Identity "Bob Barker" -CancelOrganizedMeetings -QueryStartDate 3-11-2020 -QueryWindowInDays 1 -PreviewOnly -Verbose 

While this command does as requested, you cannot selectively define which meeting room or resource to free up; the only option is to remove all calendar events this person made for a particular date. You also need to define the date in US format: mm-dd-yyyy.

Email Addresses

To update an email alias via on premise Active Directory (AD Connect):

  1. Open Active Directory Users and Computers 
  2. Locate the user in the OU
  3. Select the 'Custom Attribute' tab 
  4. Scroll down to proxyAddresses
  5. Add a proxyAddress value:

  6. The next time AD Connect synchronises the alias will appear

To set the Primary SMTP address, the proxyAddresses AD object attribute needs to have the prepending SMTP: in uppercase, as illustrated below:

All other address with a prepending lowercase smtp: will become aliases to the account:


To update email alias for an Azure/Office 365 admin account: 

Get-MsolUser -UserPrincipalName 
Set-MsolUser -UserPrincipalName -AlternateEmailaddresses 
Office 365 Groups

At the time of writing, you can't add email aliases or create a redirect rule to Office 365 Groups. However, an alias email can be added via Exchange Online PowerShell: 

Get-UnifiedGroup -Identity
Set-UnifiedGroup -Identity -EmailAddresses @{Add=""} 

To change the email Primary SMTP address: 

Set-UnifiedGroup -Identity "Office365Group" -PrimarySmtpAddress "" 

To set Mail enabled Office 365 Groups to be visible in Global Address List (GAL): 

  1. First begin by listing all groups:

    Get-UnifiedGroup | Where-Object {$_.AccessType -eq 'Private'} | Sort-Object whencreated | Out-GridView 

  2. Make the groups’ email address visible in Outlook:

    Set-UnifiedGroup -Identity Team-Accounting -HiddenFromExchangeClientsEnabled:$False 

Note: Changing the value from $False to $True hides the groups’ address in the Global Address List.

Mailbox Restoration

There are a couple of ways to do this; either restore the account or perform a soft-delete restore. I will discuss both options and when to use them.

Soft-delete from Azure AD or Active Directory (AD) on premise:

If the account was deleted within 30 days, simply restore the deleted object either from Azure AD or on premise AD; if the latter, also perform an Azure AD Connect sync, allowing 30 minutes to an hour for the mailbox to reappear. Confirm that the Primary SMTP and alias addresses are correct.

Restoring user's mailbox: 

Assuming you have a Retention Policy enabled and how it's configured, you can recover a deleted user's mailbox past 30 days by performing a soft-delete restore.
Examples where this is applicable could be rehire requiring access to their prior emails, accidental deletion of a user who was on extended leave, restoring a mailbox to a new hire working on a project, etc... 

Note: For an on premise AD account, restore or recreate the users AD account and perform a Azure AD Connect sync and wait 30 minutes for the synchronization to occur.

  1. Confirm that the account has been restored and their license has been applied
  2. Connect to the Exchange Admin PowerShell identity of the soft deleted mailbox:

Get-Mailbox –SoftDeletedMailbox -Identity "alice.jones" | fl *ExchangeGuid*

ExchangeGuid: 11223344-1234-1234-1234-112233445566 

  1. Retrieve the identity of the newly created mailbox for the restored account:

Get-Mailbox -identity "alice.jones" | fl *ExchangeGuid*

ExchangeGuid: 55667788-6789-6789-6789-778899001122

  1. Request a mailbox restore request, mapping the source mailbox (soft-deleted) to the newly provisioned (empty) mailbox:

New-MailboxRestoreRequest -SourceMailbox "11223344-1234-1234-1234-112233445566" -TargetMailbox "55667788-6789-6789-6789-778899001122" -AllowLegacyDNMismatch

Note: Depending on the size of the soft-deleted mailbox, this may take several minutes to hours to complete the restore. 

  1. Confirm the restore status: 

  1. Finally, monitor the Item count increasing until the figure stops, indicating the mailbox has been restored: 

Get-MailboxStatistics -Identity alice.jones
Room Bookings

Room Finders are essentially distribution lists; to view existing lists: 


To remove a Room Finder list: 

Remove-DistributionGroup -Identity

To create a Room Finder list: 

New-DistributionGroup -Name "Available Rooms" –PrimarySmtpAddress "" –RoomList 

$Rooms = Get-Mailbox -RecipientTypeDetails RoomMailbox |Where-Object {$_.Alias -ne 'CommonRoom'} | select -ExpandProperty Alias 
$Rooms | Add-DistributionGroupMember -Identity "Available Rooms" 

Extend Meeting Room booking days:

Get-MailBox "Meeting Room 1" | Set-CalendarProcessing -BookingWindowInDays 365 

You can achieve the same under the Exchange admin center > recipients > resources > open the resource > under 'booking options' update the 'Maximum booking lead time (days):' to the desired value.

Review Mailbox Forwarding and Delegation Access

Below is a script that will query Azure AD and Exchange Online and will generate three CSV files, detailing user mail rules, external forwarding rules and users who have delegated access to other mailboxes.
This is great for regular audits to ensure your Exchange posture is updated, following up or revoking unnecessary forwarding rules and delegations when people have moved around the organization.

# Connect to Azure AD and Exchange Online 

$allUsers = @()
$AllUsers = Get-MsolUser -All -EnabledFilter EnabledOnly | Select-Object ObjectID, UserPrincipalName, FirstName, LastName, StrongAuthenticationRequirements, StsRefreshTokensValidFrom, StrongPasswordRequired, LastPasswordChangeTimestamp | Where-Object {($_.UserPrincipalName -notlike "*#EXT#*")}

$UserInboxRules = @()
$UserDelegates = @()

foreach ($User in $allUsers)
Write-Host "Checking inbox rules and delegates for user: " $User.UserPrincipalName;
$UserInboxRules += Get-InboxRule -Mailbox $User.UserPrincipalname | Select-Object Name, Description, Enabled, Priority, ForwardTo, ForwardAsAttachmentTo, RedirectTo, DeleteMessage | Where-Object {($_.ForwardTo -ne $null) -or ($_.ForwardAsAttachmentTo -ne $null) -or ($_.RedirectsTo -ne $null)}
$UserDelegates += Get-MailboxPermission -Identity $User.UserPrincipalName | Where-Object {($_.IsInherited -ne "True") -and ($_.User -notlike "*SELF*")}

$SMTPForwarding = Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,ForwardingAddress,ForwardingSMTPAddress,DeliverToMailboxandForward | where {$_.ForwardingSMTPAddress -ne $null}

$UserInboxRules | Export-Csv .\MailForwardingRulesToExternalDomains.csv
$UserDelegates | Export-Csv .\MailboxDelegatePermissions.csv
$SMTPForwarding | Export-Csv .\Mailboxsmtpforwarding.csv

Open the exported CSV files to review the forwarding rules and delegations.