How to convert existing primary email addresses to lowercase, as well as ensuring that any new mailboxes also have lowercase primary email address.
You may want to make sure your users have their email addresses in lower case. This can be useful for the following reasons:
- It just looks tidier, in Exchange/AD but also in Outlook when users view users details in the address book.
- You may have applications that are using email address for SSO (can can’t use UPN for whatever reason and you haven’t been able to match email and UPN), but are also case sensitive (e.g. Salesforce).
So we need to do 2 things:
- Edit the email address policy in Exchange to ensure that all new users will have lowercase email.
- Convert email addresses for existing mailboxes.
Unfortunately it is not possible to edit the email address policies in Exchange Online, because they don’t actually do anything.
However, if you still have on-prem AD, and therefore you should have an Exchange Hybrid server for mailbox creation and management, you can set the policy there (you should be using that to create all your Exchange Online mailboxes anyway).
Disclaimer: you may have issues with users having to reauthenticate on mobile, or recreate their Outlook profiles. Test these changes first before wider deployment.
First, check your email address policies, you may well just have the default policy as below:
Get-EmailAddressPolicy | select Name,EnabledPrimarySMTPAddressTemplate
Now, we’ll update this to be the same format (first.last) but in lowercase:
Set-EmailAddressPolicy -Identity "Default Policy" -EnabledPrimarySMTPAddressTemplate "%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz%g.%[email protected]"
Note: you can see what variables are available here: https://docs.microsoft.com/en-us/exchange/email-addresses-and-address-books/email-address-policies/email-address-policies?view=exchserver-2019
Now when you create a user, it will all be in lowercase:
Next, we need to convert existing users. Since Exchange does not differentiate between upper and lower case. Use the following script for remote (Exchange Online) mailboxes, connecting to your on-prem Exchange server first (modified from https://mikecrowley.us/2012/05/14/converting-smtp-proxy-addresses-to-lowercase/).
Note that the only impact we found in a live environment for several hundred users, was that users of iOS mail would be prompted for their password again. Outlook on desktop or mobile was unaffected.
# Script converts the primary email address to lowercase
$ErrorActionPreference = "SilentlyContinue"
#Connect to Exchange 2016
."$PSScriptRoot\..\Connections\ConnectExchange2016.ps1"
$OU = "OU=Users,DC=domain,DC=com"
$ADusers = Get-ADUser -Filter 'enabled -eq $true' -SearchBase $OU -properties Mail | sort-object Mail
$count = $ADusers.count
Write-Host "$count enabled users in the OU:" -ForegroundColor Cyan
foreach ($user in $ADusers){$user.Mail}
$TargetObjects =@()
foreach ($user in $ADusers) {
$TargetObject = Get-RemoteMailbox -Identity $user.samaccountname | Where {$_.PrimarySmtpAddress.ToLower() -cne $_.PrimarySmtpAddress} # To get just one user
if ($TargetObject) {
$TargetObjects += $TargetObject}
}
if (!$TargetObjects) {
write-host "No mailboxes found with uppercase characters, exiting" -ForegroundColor yellow
} else {
write-host "Total mailboxes with uppercase characters:" $TargetObjects.count
write-host "Selecting the first 30"
$TargetObjects = $TargetObjects | select -first 30
$count = $TargetObjects.count
Write-Host "The following $count mailboxes have uppercase characters in PrimarySmtpAddress and will be converted" -ForegroundColor Cyan
$TargetObjects.PrimarySmtpAddress
Read-host -prompt "Press any key to continue or CTRL+C to quit"
#Backup First
Function Get-FileFriendlyDate {Get-Date -format ddMMMyyyy_HHmm.s}
$DesktopPath = ([Environment]::GetFolderPath("Desktop") + '\')
$LogPath = ($DesktopPath + (Get-FileFriendlyDate) + "-UppercaseBackup.xml")
$TargetObjects | select DistinguishedName, PrimarySMTPAddress, EmailAddresses | Export-Clixml $LogPath
Write-Host "A backup XML has been placed here:" $LogPath -ForegroundColor Cyan
Write-Host
$Counter = $TargetObjects.Count
foreach ($RemoteMailbox in $TargetObjects) {
Write-Host "Old address: " -ForegroundColor DarkCyan -NoNewline
Write-Host $RemoteMailbox.PrimarySmtpAddress -ForegroundColor Cyan
Write-Host "New address: " -ForegroundColor DarkCyan -NoNewline
Write-Host $RemoteMailbox.PrimarySmtpAddress.ToLower() -ForegroundColor Cyan
Set-RemoteMailbox $RemoteMailbox.Identity -PrimarySmtpAddress ("TMP-Rename-" + $RemoteMailbox.PrimarySmtpAddress) -EmailAddressPolicyEnabled $false
Set-RemoteMailbox $RemoteMailbox.Identity -EmailAddresses @{remove = $RemoteMailbox.PrimarySmtpAddress}
Set-RemoteMailbox $RemoteMailbox.Identity -PrimarySmtpAddress $RemoteMailbox.PrimarySmtpAddress.ToLower()
Set-RemoteMailbox $RemoteMailbox.Identity -EmailAddresses @{remove = ("TMP-Rename-" + $RemoteMailbox.PrimarySmtpAddress)}
Set-RemoteMailbox $RemoteMailbox.Identity -EmailAddressPolicyEnabled $true
}
Write-Host
Write-Host "Done." -ForegroundColor DarkCyan
#End
}