Change all AD users email addresses [PowerShell]

Recently I had the need to change all users email addresses in an Active Directory domain from one domain name to another. The below PowerShell is how I did it.

The customer was using Office 365 with AD Connect. So, any user email address changes needed to be made within the source on premise AD Domain rather than within Office 365 or Azure AD. AD Connect would then replicate the changes to Office 365 / Azure AD

The below script checks if each user has an email on the old domain and if so it adds an equivalent on the new domain name. The script will do this this for the primary email address as well as any aliases the user may have on the old domain name. Any email addresses on the old domain name are retained as aliases. So the users primary (outgoing) email will moved onto the new domain name, but the old domain will still exist as aliases, so they can still be emailed on the old.

The script generates an output as it goes of all the changes it is making.

You will need to have the appropriate permissions to edit the user accounts and the script needs to be run from an admin PowerShell windows.

I highly recommend you test this against a group of users in a test OU or against an isolated clone of a domain controller.

But the script will not submit any changes to AD while the line “$result = Set-ADUser -Instance $user” is commented out.

Changes to make

  • $oldDomain – The old domain name “MyComany.co.uk”
  • $newDomain – The new domain name we want to change to “MyNewComany.co.uk”
  • $userou – The group of users to target “DC=mycompany,DC=co,DC=uk”
  • Once you are ready to make changes to AD you will need to uncomment line 204 “$result = Set-ADUser -Instance $user” towards the end of the script

The Script

$oldDomain = "olddomaname.tld"
$newDomain = "newdomainname.tld"
$userou = 'OU=TestOU,DC=domain,DC=com'

$users = Get-ADUser -Filter * -SearchBase $userou -Properties SamAccountName, EmailAddress, ProxyAddresses

Foreach ($user in $users) {
	$mailAttributeNull = $true
	$primaryProxyNull = $true
	$aliasProxyNull = $true
	
	$currentEmailAddress = $null
	
	$currentEmailName = $null
	$currentEmailDomain = $null
	
	$currentProxyType = $null
	$currentProxyEmail = $null
		
	$currentProxyName = $null
	$currentProxyDomain = $null
	
	$proxiesToRemove = @()
	$proxiesToAdd = @()

	Write-Host
	Write-Host "==================================================" -ForegroundColor White -BackgroundColor DarkBlue
	Write-Host "User: $($user.samaccountname)" -ForegroundColor White -BackgroundColor DarkBlue
	Write-Host "==================================================" -ForegroundColor White -BackgroundColor DarkBlue
	
	# ---------------------------------------
	# Update Mail Attribute  
	# ---------------------------------------
	Write-Host 
	Write-Host "Updating Mail Attribute"
	Write-Host "----------------------------------------"
	$currentEmailAddress = $user.EmailAddress
	
	if ($currentEmailAddress) {
		Write-Host "   Current Email: " $currentEmailAddress
		$mailAttributeNull = $false
			
		$currentEmailName = $currentEmailAddress.Split("@")[0]
		$currentEmailDomain = $currentEmailAddress.Split("@")[1]
		
		If ($currentEmailDomain -ieq $oldDomain) {
			$newemail = -join($currentEmailName, "@",$newDomain)
			Write-Host "   New Email: " $newemail 
			
			$user.EmailAddress = $newemail
		}
		Elseif ($currentEmailDomain -ieq $newDomain) {
			Write-Host "   Mail Attribute: New Value Detected Skipping..."
			Write-Host "   Value: $($user.EmailAddress)"
		}
		Else {
			Write-Host "   Not a domain we are interesting in, skipping..."
		}
	} else {
			$mailAttributeNull = $true
			Write-Host "   Mail Attribute: Empty  Skipping..."
	}
	
	# ---------------------------------------
	# Update Proxy Addresses  
	# ---------------------------------------
	Write-Host 
	Write-Host "Updating Proxy Addresses"
	Write-Host "----------------------------------------"
	
	ForEach ($proxy in $user.ProxyAddresses) {
	
		Write-Host "  PROCESSING : " $proxy
		$currentProxyType = $proxy.Split(":")[0]  #Before the : SMTP or smtp
		$currentProxyEmail = $proxy.Split(":")[1] #After the : [email protected]
		
		$currentProxyName = $currentProxyEmail.Split("@")[0] #Before the @ firstname.surname
		$currentProxyDomain = $currentProxyEmail.Split("@")[1] #After the @ domain.tld
	
		If ($currentProxyType -ceq "SMTP") {
			# -------------------------------------
			#Process the primary address
			# -------------------------------------
			$primaryProxyNull = $false
			
			Write-Host "      ** PRIMARY (SMTP:)" -ForegroundColor White -BackgroundColor DarkGreen
			
			If ($currentProxyDomain -ieq $oldDomain) {
				# Found the primary proxy was on the old domain, change the primary to the new domain and move the old primary to an alias.
				Write-Host "      Its on the old domain, updating..."
				$newPrimaryProxy = -join("SMTP:", $currentProxyName, "@",$newDomain)
				$newAliasProxy = -join("smtp:", $currentProxyName, "@",$oldDomain)
				
				Write-Host "         New Primary Proxy: " $newPrimaryProxy
				Write-Host "         New Alias Proxy: " $newAliasProxy
				
				$proxiesToRemove += $proxy
				$proxiesToAdd += $newPrimaryProxy
				$proxiesToAdd += $newAliasProxy
				
			} elseif ($currentProxyDomain -ieq $newDomain) {
					Write-Host "      Already on the new domain, skipping..."			
			} else {
					Write-Host "      Not a domain we are interesting in, skipping..."
			}
		} elseif ($currentProxyType -ceq "smtp") {
			# -------------------------------------
			#Process the alias addresses
			# -------------------------------------
			$aliasProxyNull = $false
			
			Write-Host "      * Alias (smtp:)"
			
			If ($currentProxyDomain -ieq $oldDomain) {
				# Found the alias proxy was on the old domain, change the alias to the new domain and move the old alias to an alias.
				Write-Host "      On the old domain, adding a copy on the new domain..."
				$newAliasProxy = -join("smtp:", $currentProxyName, "@",$newDomain)
				
				Write-Host "         New Alias Proxy: " $newAliasProxy
				$proxiesToAdd += $newAliasProxy
				
			} elseif ($currentProxyDomain -ieq $newDomain) {				
				#Check is this is a duplicate of the new primary proxy
				$currentDuplicateProxyCheck = -join("SMTP:", $currentProxyEmail)
					
				if ($currentProxyEmail -ieq $newemail)
				{
					#This is a duplicate of the primary address so will remove it
					Write-Host "      This is a duplicate of the primary address so will remove it"	
					$proxiesToRemove += $proxy
				}
					
					Write-Host "      Already on the new domain, skipping..."	
			} else {
					Write-Host "      Not a domain we are interesting in, skipping..."
			}
		}

	}
	
	#Deal with there not being a proxy address
	if ($primaryProxyNull -eq $true -And $mailAttributeNull -eq $false) {
		#Proxy is empty but mail has a value
		Write-Host "   No proxy addresses set, setting up..."
			
		$newPrimaryProxy = -join("SMTP:", $currentEmailName, "@",$newDomain)
		$newAliasProxy = -join("smtp:", $currentEmailName, "@",$oldDomain)
			
		Write-Host "      New Primary Proxy: " $newPrimaryProxy
		Write-Host "      New Alias Proxy: " $newAliasProxy
			
		$proxiesToAdd += $newPrimaryProxy
		$proxiesToAdd += $newAliasProxy
		
	} elseif ($primaryProxyNull -eq $true-And $mailAttributeNull -eq $true) {
		Write-Host "   The user does not have a mail attribute or any proxy addresses, skipping user..."  -ForegroundColor White -BackgroundColor DarkRed
	}
	
	# -------------------------------------
	# Submit changes
	# -------------------------------------
	Write-Host 
	Write-Host "Proxy Changes Made"
	Write-Host "----------------------------------------"
	
	#Removals
	foreach($removeProxy in $proxiesToRemove) {

		Write-Host "   Removed " $removeProxy
		$user.ProxyAddresses.remove($removeProxy)
	}
	
	# Additions
	foreach($addProxy in $proxiesToAdd) {

		Write-Host "   Added " $addProxy
		$user.ProxyAddresses.add($addProxy)
	}
	
	# -------------------------------------
	# FINAL RESULT
	# -------------------------------------
	Write-Host 
	Write-Host "FINAL RESULT"
	Write-Host "----------------------------------------"
	$currentEmailAddress = $user.EmailAddress
	
	if ($currentEmailAddress) {
		Write-Host "   Mail Attribute is now:" $currentEmailAddress
	} else {
		Write-Host "   Mail Attribute is blank"
	}

	Write-Host ""
	Write-Host "   Proxy addresses are:"
	ForEach ($proxy in $user.ProxyAddresses) {
		Write-Host "      " $proxy
	}	

    Write-Host "Setting Values..."
	# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	# Un-comment the below to update AD
	#
    #$result = Set-ADUser -Instance $user
	# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	Write-Host
	Write-Host "**************************************************" 
	Write-Host
}

3 thoughts on “Change all AD users email addresses [PowerShell]”

  1. Thank you so so very much for sharing your script. As I am learning PS on the fly, I am trying to piece together what I am learning to accomplish this. Your script is very easy to understand. Thank you!

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.