Entra / Microsoft 365 · Licensing
Report shared mailbox licenses
A script to analyze shared mailboxes and report if they need licenses.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-ExchangeOnline -ShowBanner:$False -ErrorAction Stop
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
$ModulesLoaded = Get-Module | Select-Object -ExpandProperty NameIf (!($ModulesLoaded -match "ExchangeOnlineManagement")) {Write-Host "Connecting to Exchange Online..."Connect-ExchangeOnline -ShowBanner:$False -ErrorAction Stop}# Define some variables$ExoPlan1 = "9aaf7827-d63c-4b61-89c3-182f06f82e5c"$ExoArchiveAddOn = "176a09a6-7ec5-4039-ac02-b2791c6ba793"$ExoPlan2 = "efb87545-963c-4e0d-99df-69c6916d9eb0" # See https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference$MailboxLimit = 50GBWrite-Host "Finding shared mailboxes..."[array]$Mbx = Get-EXOMailbox -RecipientTypeDetails SharedMailbox -Properties ProhibitSendReceiveQuota, ArchiveGuid, ArchiveName, ArchiveStatus, AutoExpandingArchiveEnabled, PrimarySmtpAddress, LitigationHoldEnabled -ResultSize UnlimitedIf (!($Mbx)) {Write-Host "Can't find any shared mailboxes - exiting!" ; break} Else {Write-Host ("Found {0} shared mailboxes" -f $Mbx.count)}[int]$i = 0$SharedMbxReport = [System.Collections.Generic.List[Object]]::new()ForEach ($M in $Mbx) {$i++Write-Host ("Processing mailbox {0} ({1} of {2})" -f $M.DisplayName, $i, $Mbx.count)$NeedsLicense = $false; $ExoArchiveLicense = $false; $ExoPlan2License = $false; $ArchiveStats = $null$MailboxOverSize = $false; $ExoPlan1License = $false; $ArchiveMbxSize = $null$MbxStats = Get-ExoMailboxStatistics -Identity $M.ExternalDirectoryObjectId$MbxSize = [math]::Round(($MbxStats.TotalItemSize.Value.toBytes() / 1GB),5)If ($M.ArchiveStatus -ne "None") { #Mailbox has an archive$ArchiveStats = Get-ExoMailboxStatistics -Archive -Identity $M.ExternalDirectoryObjectIdIf ($ArchiveStats) {$ArchiveMbxSize = [math]::Round(($ArchiveStats.TotalItemSize.Value.toBytes() / 1GB),5)}}# Check licenses assigned to the mailbox's Entra ID account$Licenses = Get-MgUserLicenseDetail -UserId $M.ExternalDirectoryObjectId | Select-Object -ExpandProperty ServicePlans | Where-Object {$_.ProvisioningStatus -eq "Success"} | Sort-Object ServicePlanId -UniqueIf ($Licenses) { # The mailbox has some licensesIf ($ExoArchiveAddOn -in $Licenses.ServicePlanId) {$ExoArchiveLicense = $true}If ($ExoPlan2 -in $Licenses.ServicePlanId) {$ExoPlan2License = $true}If ($ExoPlan1 -in $Licenses.ServicePlanId) {$ExoPlan1License = $true}}# If the mailbox has an active archive, it needs an Exchange Online Plan 2 license unless it has an Exchange Online Archiving add-on licenseIf ($M.ArchiveStatus -eq "Active") {If ($ExoPlan2License -eq $false) {$NeedsLicense = $true}If ($ExoPlan1License -eq $true -and $ExoArchiveLicense -eq $true) { 1$NeedsLicense = $false}}# Mailbox is on litigation hold and it doesn't have an Exchange Online Plan 2 licenseIf ($M.LitigationHoldEnabled -eq $true -and $ExoPlan2License -eq $false) {$NeedsLicense = $true}# Mailbox is over the 50GB usual quota for shared mailboxes and doesn't have an Exchange Online Plan 2 licenseIf ($MbxStats.TotalItemSize.value -gt $MailboxLimit -and $ExoPlan2License -eq $false) {$MailboxOverSize = $true$NeedsLicense = $true} Else {$MailboxOverSize = $false}$ReportLine = [PSCustomObject][Ordered]@{ # Write out details of the private channel and its membersMailbox = $M.DisplayNameUPN = $M.PrimarySmtpAddressNeedsLicense = $NeedsLicenseMailboxSizeGB = $MbxSizeMailboxItems = $MbxStats.ItemCountMailboxOverSize = $MailboxOverSizeArchive = $M.ArchiveStatusArchiveSizeGB = $ArchiveMbxSizeArchiveItems = $ArchiveStats.ItemCountLitigationHoldEnabled = $M.LitigationHoldEnabledExoPlan1 = $ExoPlan1LicenseExoPlan2 = $ExoPlan2LicenseExoArchiveAddOn = $ExoArchiveLicense}$SharedMbxReport.Add($ReportLine)} #End ForEach $Mbx[array]$NeedsLicenseList = $SharedMbxReport | Where-Object {$_.NeedsLicense -eq $True}Write-Host " "Write-Host ("{0} shared mailboxes scanned" -f $Mbx.count)If ($NeedsLicenseList) {Write-Host ("{0} mailbox(es) need an Exchange Online Plan 2 license" -f $NeedsLicenseList.count)Write-Host ("Licenses must be assigned to the following mailboxes: {0}" -f $NeedsLicenseList.Mailbox -join ", " )$NeedsLicenseList | Format-Table Mailbox, MailboxOverSize, Archive, LitigationHoldEnabled} Else {Write-Host "Congratulations! All of your shared mailboxes are properly licensed."}$SharedMbxReport | Out-GridView
Attribution
Author
Office365itpros