Remove Users from Office 365 Using PowerShell

Today, we are going to create a PowerShell script to remove a user’s access from Office 365.  I had to come up with something because, at an MSP, we have many clients who use Office 365 for their email service.  Not all of them have it synced with Active Directory.  When we offboard a user from Office 365, we have ensure the following things get done.

  • Convert the user’s mailbox to a shared mailbox.
  • Grant designated persons access to the mailbox.
  • Forward the incoming emails to someone else.
  • Remove the user from any groups they may be a member of.
  • Disable ActiveSync
  • Block the user’s access
  • Remove the assigned license.
  • Email the account manager to let them know the license was removed.

If you were to do that manually, it would take a long time.  When you’re working a busy service desk, time is a luxury.  It was this lack of time that drove me to cobble together a script that will do all that for me.

Now, I am not an expert on PowerShell.  I’m just good at searching the internet for snippets of code and adapting them to do what I need.  As a result, my scripts are sloppy, but effective.


Before you can use this script, you need to install two things on your PC.  Without them, the script will not work.  This article does a good job of explaining these prerequisites in detail.  At the bare minimum, you will need:

Once you have those installed, you’ll want to run the below cmdlet to allow signed scripts to run.

Set-ExecutionPolicy RemoteSigned

Building the Script

$credential = Get-Credential
Import-Module MsOnline
Connect-MsolService -Credential $credential
$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri “” -Credential $credential -Authentication “Basic” -AllowRedirection
Import-PSSession $exchangeSession -DisableNameChecking

The above block of code establishes the connection to Office 365 and imports the necessary modules.  Specifically, Exchange and Microsoft Online.  The first thing it does is prompt for credentials.  The credentials used must be an administrator in the organization.

Next, we need to declare some variables for the email being sent.

$mailRecipient = “”
$mailSMTP = “”
$mailFrom = Read-host “Please enter your email address”
$domain = (Get-MsolDomain).Name[0]
$mailSubject = “License removal for $domain

These values will give us the building blocks of the email being sent to the account manager.  You will need to customize them to fit your needs.

$mailbox = Read-Host “What is the email address of the departing user?”
Write-Host “`n”
Write-Host “Office 365 shared mailboxes are limited to 50GB. `nConverting mailboxes larger than 50GB may not work as intended.”
$sizeGet-Mailbox -identity $mailbox| Get-MailboxStatistics | Select TotalItemSize
Write-Host “The current size of the mailbox is $size

Next thing we need is the identity of the departing user.  We get this by specifying the user’s email address.  The script will query the mailbox and display the size of the mailbox.  This will allow you to make an informed decision on whether to convert it to a shared mailbox or not.

$title = “Convert to shared mailbox?”
$message = “Do you want to convert the mailbox to shared?
$yesNew-Object System.Management.Automation.Host.ChoiceDescription “&Yes”, “Convert mailbox to shared.”
$noNew-Object System.Management.Automation.Host.ChoiceDescription “&No”, “Do not convert mailbox to shared.”
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

$result = $host.ui.PromptForChoice($title, $message, $options, 0)switch ($result)

0 {
$accessuser = @()
$more = “y”
do {
$user = Read-Host “Please enter the email address of the user needing access.”
$accessuser += ,@($user)
Write-Host “`n”
$more = Read-Host “add another? y/n”
Write-Host “`n”
until ($more -eq “n”)
Write-Host “Converting to shared mailbox…”
Get-Mailbox -Identity $mailbox | Set-Mailbox -Type Shared
Write-Host “Done”
Write-Host “`nAdding permissions…”
foreach ($a in $accessuser) {
Add-MailboxPermission $mailbox -User ((Out-String -InputObject $a).Trim()) -AccessRights FullAccess
Write-Host “Done”
1 {}

The above block asks if you wish to convert the mailbox to shared.  If you elect to do so, the script will populate an array with email addresses you enter.  Once you finished entering the email addresses, the script will convert the mailbox to shared and grant those users full access permissions.

$title = “Set forwarding?”
$message = “Does the email need to be forwarded?
$yesNew-Object System.Management.Automation.Host.ChoiceDescription “&Yes”, “Set forwarding on mailbox.”
$noNew-Object System.Management.Automation.Host.ChoiceDescription “&No”, “Do not set forwarding on mailbox.”
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)switch ($result)
0 {
$forward = Read-Host “Please enter the forwarding destination email address.”
Write-Host “`nSetting forwarding…”
Set-Mailbox -Identity $mailbox -ForwardingAddress $forward -DeliverToMailboxAndForward $false
Write-Host “`nDone”
1 {}

Similar to the block dealing with mailbox access, the above block asks if you need to set a forward on the mailbox.  Since forwarding only accepts a single email address, there is no need for a loop to process input of multiple addresses.  If you need to forward the email to more than one destination, you can create a distribution group consisting of the users who need the email forwarded to them and forward the email there.

At this point, the script is done asking for user input.  The next thing to do is remove the user from any distribution groups.

Write-Host “Removing user from distribution groups.”
$dn = (Get-Mailbox $mailbox).DistinguishedName
$Filter = “Members -like “”$dn“””
$DGs = (Get-DistributionGroup -ResultSize Unlimited -Filter $Filter).Identityforeach ($dg in $DGs) {

Remove-DistributionGroupMember -Identity $dg -Member $mailbox -Confirm $false

The script will query all distribution groups and only enumerate ones that contain the departing user as a member.  It will then remove that user from the distribution group.  The next thing for the script to do is to remove the license and terminate access.

Write-Host “Removing assigned licenses and terminating access…”
$license = (Get-MsolUser -UserPrincipalName $mailbox).Licenses[0].AccountSkuId
Set-MsolUserLicense -UserPrincipalName $mailbox -RemoveLicenses $license
Set-MsolUser -UserPrincipalName $mailbox -BlockCredential $true
Set-CasMailbox -Identity $mailbox -ActiveSyncEnabled $false
Set-MsolUserPassword -UserPrincipalName $mailbox
Write-Host “Done”

The final steps are to send an email to the account manager to ask them to update the client’s account so they are not billed for a license that is not in use.  After that, we can gracefully terminate the script.

$mailMessage = “Please be advised that one $license is no longer in use for client with domain $domain.  Please update your records accordingly.”
Send-MailMessage -To $mailRecipient -SmtpServer $mailSMTP -From $mailFrom -Subject $mailSubject -Body $mailMessage
Remove-PSSession $exchangeSession
Write-Host “Script Complete”

There you have it.  A nice PowerShell script that takes a task that used to take 20 minutes and completes it in less than a minute.

You can customize the mail message to fit your needs as well as the recipients.  There are other parameters in the Send-MailMessage cmdlet that you may or may not need in order for it to work properly.

How have you adapted this script to work for you?  Share it in the comments below.