Office 365 duplicate mailbox cleanup

By steve, 8 September, 2020

If an organisation has AADSync set up without exchange hybrid sync, it is possible for a user to have mailboxes both in Office 365 and on-premises. Assuming that there is no mail in Office 365, the following powershell will clean up the old attributes.

Note: if anything uses the Office 365 mailbox (e.g. Teams person to person chat), this data will be lost.

#Import-Module ExchangeOnlineManagement
#Connect-ExchangeOnline
#Import-Module MSOnline 
#Connect-MsolService

function IsExchangeService([String] $ServiceName) {
	if ($ServiceName -match "EXCHANGE" -and $ServiceName -ne "EXCHANGE_ANALYTICS" -and $ServiceName -ne "EXCHANGE_S_FOUNDATION") { 
		return $true 
	}
	if ($ServiceName -eq "THREAT_INTELLIGENCE" -or $ServiceName -eq "O365_SB_Relationship_Management") {
		return $true
	}
	return $false
}

$allUsers=Get-MsolUser -all
foreach ($user in $allUsers) {
	foreach($license in $user.Licenses) {
		$ExchangeServices = $license.ServiceStatus | ? { (IsExchangeService($_.ServicePlan.ServiceName)) -and $_.ProvisioningStatus -ne "Disabled" }
		if($ExchangeServices.Count -gt 0) {
			$DisabledServices = $license.ServiceStatus | ? { $_.ProvisioningStatus -eq "Disabled" }
			$ThisDisable = @()
			# Disable all services that are already disabled
			foreach($s in $DisabledServices) {
				Write-Host ("Leaving " + $s.ServicePlan.ServiceName + " disabled for " + $user.DisplayName)
				$ThisDisable += $s.ServicePlan.ServiceName
			}
			# Disable all exchange services
			foreach($s in $ExchangeServices) {
				Write-Host ("Disabling " + $s.ServicePlan.ServiceName + " for " + $user.DisplayName)
				$ThisDisable += $s.ServicePlan.ServiceName
			}
			$LO=New-MsolLicenseOptions -AccountSkuId $license.AccountSkuId -DisabledPlans $ThisDisable
			# Make the changes
			$user | Set-MsolUserLicense -LicenseOptions $LO

			# Reset all exchange attributes
			Set-User $user.UserPrincipalName -PermanentlyClearPreviousMailboxInfo -Confirm:$false
		}
	}
}

After the above has run, you can re-configure AAD sync to enable Exchange Hybrid sync. Once you have confirmed that the attributes have synced, you can run the following to re-enable the Office 365 exchange license, which should result in Office 365 recognising the on-premises mailbox:

#Import-Module ExchangeOnlineManagement
#Connect-ExchangeOnline
#Import-Module MSOnline 
#Connect-MsolService

function IsExchangeService([String] $ServiceName) {
	if ($ServiceName -match "EXCHANGE" -and $ServiceName -ne "EXCHANGE_ANALYTICS" -and $ServiceName -ne "EXCHANGE_S_FOUNDATION") { 
		return $true 
	}
	if ($ServiceName -eq "THREAT_INTELLIGENCE" -or $ServiceName -eq "O365_SB_Relationship_Management") {
		return $true
	}
	return $false
}


#$allUsers=Get-MsolUser -all | ? { $_.DisplayName -match "Test" }
$allUsers=Get-MsolUser -all
foreach ($user in $allUsers) {
	foreach($license in $user.Licenses) {
		$ExchangeServices = $license.ServiceStatus | ? { (IsExchangeService($_.ServicePlan.ServiceName)) -and $_.ProvisioningStatus -eq "Disabled" }
		if($ExchangeServices.Count -gt 0) {
			$DisabledServices = $license.ServiceStatus | ? { $_.ProvisioningStatus -eq "Disabled" -and -not (IsExchangeService($_.ServicePlan.ServiceName)) }
			$ThisDisable = @()
			# Disable all services that are already disabled
			foreach($s in $DisabledServices) {
				Write-Host ("Leaving " + $s.ServicePlan.ServiceName + " disabled for " + $user.DisplayName)
				$ThisDisable += $s.ServicePlan.ServiceName
			}
			# Disable all exchange services
			foreach($s in $ExchangeServices) {
				Write-Host ("Enabling " + $s.ServicePlan.ServiceName + " for " + $user.DisplayName)
			}
			$LO=New-MsolLicenseOptions  -AccountSkuId $license.AccountSkuId -DisabledPlans $ThisDisable
			# Make the changes
			$user | Set-MsolUserLicense -LicenseOptions $LO
		}
	}
}

Comments