UPN Suffix Changes – The Cool Way

We’re migrating to Okta in a few weeks and are preparing our domain for the change. Our organization has a legacy “.local” domain and a few different external domains for email. This week we decided to move all of our UPN suffixes from the “.local” domain to our external “.com” domain to prepare. This does a couple things for us – First, we have configured Okta to only recognize that domain for sign in, so it will only import the users we have moved to that domain suffix. Second, it fixes a ton of autodiscover issue we have faced for years as Office 365 users. If you have a “.local” domain, you know what I’m talking about.

So how do we achieve this? You could use the GUI, but the GUI is for chumps, and you don’t want to be a chump do you? The obvious answer is PowerShell, so here’s how you do it the cool way.

Get-ADUser -Filter {userPrincipalName -like '*@OldDomain.local'} -SearchBase "OU=Testing,OU=Users,OU=Company,DC=Domain,DC=local" | ForEach-Object {
    $newUpn = $_.UserPrincipalName.Replace('OldDomain.local','NewDomain.com')
    Write-Output "Old UPN is $($_.UserPrincipalName)"
    $_ | Set-ADUser -UserPrincipalName $newUpn
    Write-Output "New UPN is $(Get-ADUser $_ | select -expand UserPrincipalName)`n"
}

I’ll walk you through this. In the first line we’re getting all AD users within two constraints.

Get-ADUser -Filter {userPrincipalName -like '*@OldDomain.local'} -SearchBase "OU=Testing,OU=Users,OU=Company,DC=Domain,DC=local" | ForEach-Object

The filter looks at all users with the userPrincipalName that includes @OldDomain.local, you would use your old UPN suffix here. The second constraint is the search base, this is saying, “Only look in OU=Testing,OU=Users,OU=Company,DC=Domain,DC=local for users to change”.  From there it uses a ForEach-Object loop to parse through each user meeting these criteria.

$newUpn = $_.UserPrincipalName.Replace('OldDomain.local','NewDomain.com')

This first line within the loop defines a variable $newUpn which is equal to $_, ie. that iterations full user principal name, but we’re replacing OldDomain.local with NewDomain.com.

$_ | Set-ADUser -UserPrincipalName $newUpn

This last line is where the magic happens. You’re piping $_ (The current iteration user) into a Set-ADUser command where we set the UserPrincipalName attribute to that fancy $newUpn variable we saved a step ago.

This iterates for as many users as it finds within that criteria, and I’ve tossed in some output logging just to describe the changes as they are happening. If you’re not into that, just take those lines out.

Now whether you have 10 users or 10,000 users – Powershell is clearly the way to go. It eliminates human error from repetitive steps, and it makes you not a chump. Plus spending time scripting rather than manually changing attributes is just more fun anyway right? Anyway, this is the cool way to achieve this task, but the really really really cool way? That’s making a function. More on that in my next blog post.