Find and remove unnecessary licenses on shared mailboxes in your own Office 365 tenant

Remove Unnecessary Licenses from Office 365 Shared Mailboxes

 

I’ve had a few requests to add a version of this script which you can run across a single tenant.

Below is the updated script for a single Office 365 tenant. The method to run it is the same as the original.

Note that this script does not support MFA on the admin account.

 

PowerShell Script to find and remove licenses from Shared Mailboxes in Office 365

#Establish a PowerShell session with Office 365. You'll be prompted for your Admin credentials
$Cred = Get-Credential
Connect-MsolService -Credential $Cred

$CSVpath = "C:\Temp\LicensedSharedMailboxes.csv"
$LicenseReportpath = "C:\Temp\SharedMailboxLicenseReport.csv"
$licensedSharedMailboxes = @()

$licensedUsers = Get-MsolUser -All | Where-Object {$_.islicensed}
 
$ScriptBlock = {Get-Mailbox -ResultSize Unlimited}
$InitialDomain = Get-MsolDomain | Where-Object {$_.IsInitial -eq $true}    
$DelegatedOrgURL = "https://outlook.office365.com/powershell-liveid?DelegatedOrg=" + $InitialDomain.Name
$sharedMailboxes = Invoke-Command -ConnectionUri $DelegatedOrgURL -Credential $Cred -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection -ScriptBlock $ScriptBlock -HideComputerName -ErrorAction SilentlyContinue
$sharedMailboxes = $sharedMailboxes | Where-Object {$_.RecipientTypeDetails -contains "SharedMailbox"}
 
foreach ($mailbox in $sharedMailboxes) {
    $licensedSharedMailboxProperties = $null
    if ($licensedUsers.ObjectId -contains $mailbox.ExternalDirectoryObjectID) {
        Write-Host "$($mailbox.displayname) is a licensed shared mailbox" -ForegroundColor Yellow  
        $licenses = ($licensedUsers | Where-Object {$_.objectid -contains $mailbox.ExternalDirectoryObjectId}).Licenses
        $licenseArray = $licenses | foreach-Object {$_.AccountSkuId}
        $licenseString = $licenseArray -join ","
        Write-Host "$($mailbox.displayname) has $licenseString" -ForegroundColor Blue
        $licensedSharedMailboxProperties = @{
            DisplayName       = $mailbox.DisplayName
            EmailAddress      = $mailbox.PrimarySmtpAddress
            Licenses          = $licenseString
            TenantId          = $customer.TenantId
            UserPrincipalName = ($licensedusers | Where-Object {$_.objectid -contains $mailbox.ExternalDirectoryObjectID}).UserPrincipalName
        }
        $forcsv = New-Object psobject -Property $licensedSharedMailboxProperties
        $licensedSharedMailboxes += $forcsv
        $forcsv | Select-Object CustomerName, DisplayName, EmailAddress, Licenses | Export-CSV -Path $CSVpath -Append -NoTypeInformation
        # Create a CSV with a license report and PowerShell Cmdlets that you can use to quickly reassign licenses if you've removed them in error. 
        foreach ($license in $licenses) {
            $licenseProperties = @{
                DisplayName  = $licensedSharedMailboxProperties.DisplayName
                EmailAddress = $licensedSharedMailboxProperties.UserPrincipalName
                License      = $license.AccountSkuId
                TenantId     = $customer.TenantId
                ReAddlicense = "Set-MsolUserLicense -UserPrincipalName $($licensedSharedMailboxProperties.UserPrincipalName) -AddLicenses $($license.AccountSkuId)"
            }
            $forcsv = New-Object psobject -Property $licenseProperties
            $forcsv | Export-CSV -Path $LicenseReportpath -Append -NoTypeInformation
        }
    }
    else {   
        Write-Host "$($mailbox.DisplayName) is unlicensed"
    }
}

# Provide an option to remove the licenses from the shared mailboxes
 
Write-Host "`nFound $($licensedSharedMailboxes.Count) licensed shared mailboxes in your tenant. A list has been exported to $csvpath
A license report has been exported to $licenseReportPath, just in case you need to restore these licenses to the shared mailboxes later." -ForegroundColor Yellow
Write-Host "r: Press 'r' to remove all licenses from all shared mailboxes."
Write-Host "a: Press 'a' to be asked for each mailbox."
Write-Host "l: Press 'q' to quit and leave all licensed."
 
do {
    $input = Read-Host "Please make a selection"
    switch ($input) {
        "r" {
            Clear-Host
            Write-Host "Removing licenses from the following sharedmailboxes: `n$($licensedSharedMailboxes.userprincipalname -join ", ")"
            foreach ($mailbox in $licensedSharedMailboxes) {
                $currentLicenses = $null
                $licenses = $mailbox.Licenses -split ","
                foreach ($license in $licenses) {
                    Write-Host "Removing $license" -ForegroundColor Yellow
                    Set-MsolUserLicense -UserPrincipalName $mailbox.UserPrincipalName -removelicenses $License
                }
                $currentLicenses = (Get-MsolUser -UserPrincipalName $mailbox.UserPrincipalName).Licenses
                if (!$currentLicenses) {
                    Write-Host "License successfully removed from $($Mailbox.displayname) ($($mailbox.UserPrincipalName)): $($mailbox.Licenses)" -ForegroundColor Green
                }
                else {
                    Write-Host "License was not successfully removed from $($Mailbox.displayname) ($($mailbox.UserPrincipalName)), please remove licenses via the Office 365 Portal: $($mailbox.Licenses)" -ForegroundColor Red
                }
            }
            Read-Host "Enter q to quit."
            $input = "q"
            return
        } "a" {
            Clear-Host
            foreach ($mailbox in $licensedSharedMailboxes) {
                $mailboxChoice = $null
                do {
                    $mailboxChoice = Read-Host "Would you like to remove $($mailbox.licenses) from $($Mailbox.displayname) ($($mailbox.UserPrincipalName))? [y,n]"
                    switch ($mailboxChoice) {
                        "y" {
                            $currentLicenses = $null
                            $licenses = $mailbox.Licenses -split ","
                            foreach ($license in $licenses) {
                                Write-Host "Removing $license" -ForegroundColor Yellow
                                Set-MsolUserLicense -UserPrincipalName $($mailbox.UserPrincipalName) -removelicenses $License
                            }
                            $currentLicenses = (Get-MsolUser -UserPrincipalName $mailbox.UserPrincipalName).Licenses
                            if (!$currentLicenses) {
                                Write-Host "License successfully removed from $($Mailbox.displayname) ($($mailbox.UserPrincipalName)): $($mailbox.Licenses)" -ForegroundColor Green
                            }
                            else {
                                Write-Host "License was not successfully removed from $($Mailbox.displayname) ($($mailbox.UserPrincipalName)), please remove licenses via the Office 365 Portal: $($mailbox.Licenses)" -ForegroundColor Red
                            }
                        }
                        "n" {
                            Write-Host "Leaving $($mailbox.licenses) on $($mailbox.EmailAddress)"
                        }  
                    } Pause
                }until($mailboxchoice -eq "y" -or $mailboxChoice -eq "n")  
            }
            return
        } "q" {
            return
        }
    }
    pause
}
until ($input -eq "q")

Was this article helpful?

Related Articles