Bulk change UserPrincipalName in Active Directory via PowerShell

The estimated reading time 2 minutes

Getting things ready for cloud migration or anything different, lot’s of companies need to change their users UPNs. As consultant I had to do that several times, therefore I wrote some lines of PowerShell code, to manage this. It’s not that difficult, but for documentation my script also creates a CSV file with the UPNs before and after change. With this simple mechanism you can do a rollback easily. But first we want to change UPNs to E-Mail address. (ActiveDirectory PowerShell module needed for this script).

NOTE: before changing UPNs in ActiveDirectory, please verify if any third party software relies on UPNs (if you don’t know, just give a try by changing it manually on some users).

How does the user look like?

After running the script the user should look like this (now UPN is same like E-mail address):

NOTE: please verify the alternative logon UPN suffixes (can be found in MMC “Domains and Trusts)

The script generates two CSV files, so it is easy to compare if there are some issues.

Let’s have a look on the blank script:

$ous = "OU=MENGEN,OU=DEMO,DC=demo,DC=it-koehler,DC=com","OU=SIGMARINGEN,OU=DEMO,DC=demo,DC=it-koehler,DC=com"
[boolean]$logonly = $true
[string] $csvuserLogfilePath = "C:\temp\UPN"
  
  [string] $csvuserLogfileDate = Get-Date -Format "yyyy-MM-dd-HH-mm"
  [string] $csvuserLogfileNamePrefix = "UPN-Before"
  [string] $csvuserLogfileName = $($csvuserLogfileNamePrefix + $csvuserLogfileDate + ".csv")
  [string] $csvuserLogfile = $csvuserLogfilePath + "\" + $csvuserLogfileName

  [string] $csvuserLogfileNamePrefix = "UPN-Changed"
  [string] $csvuserLogfileName = $($csvuserLogfileNamePrefix + $csvuserLogfileDate + ".csv")
  [string] $csvuserLogfilechanged = $csvuserLogfilePath + "\" + $csvuserLogfileName
    $dcfqdn  = ((Get-ADDomainController).Hostname)
 Add-Content -Path $csvuserLogfile -Value "SamAccountName;UserPrincipalName;Mail"
 if($logonly -ne "$true"){
 Add-Content -Path $csvuserLogfilechanged -Value "SamAccountName;UserPrincipalName;Mail"
 }
foreach($ou in $ous){

    $users = (Get-ADUser -Server $dcfqdn  -Filter * -Properties * -SearchBase "$ou"   | Where-Object {$_.mail -ne $null}) 

        foreach($user in $users){
                $attribute1 = $user | Select-Object samaccountname -ExpandProperty samaccountname
                $attribute2 = $user | Select-Object userprincipalname -ExpandProperty userprincipalname
                $attribute3 = $user | Select-Object mail -ExpandProperty mail
                    Add-Content -Path $csvuserLogfile -Value "$attribute1;$attribute2;$attribute3"
                
                if($logonly -ne "$true"){
                Write-Host "set UPN $attribute3 for user $attribute1" -ForegroundColor Green 
                Set-ADUser -Server "$dcfqdn" -Identity "$user" -UserPrincipalName "$attribute3"
                $changeduser = Get-ADUser -Server $dcfqdn -Identity "$attribute1" -Properties mail | select samaccountname,userprincipalname,mail
                $change1 = $changeduser | Select-Object samaccountname -ExpandProperty samaccountname
                $change2 =  $changeduser | Select-Object userprincipalname -ExpandProperty userprincipalname
                $change3 = $changeduser | Select-Object mail -ExpandProperty mail
                Add-Content -Path $csvuserLogfilechanged -Value "$change1;$change2;$change3"
                
                 }
                
               
                }

    }

If you run it on your own machine, there has to be some modifications (Line 1-3)
You need to give it the distinguished name of OUs (can handle multiple OUs)
Logonly is set to “True” by default (so no changes made at all)
Path to the log of the CSV files.

Hope the script can help to make changing UPNs as easy as it could be.
Have fun.

Was this article helpful?
YesNo
5 1 vote
Article Rating
Subscribe
Notify of
guest
4 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
Buddy Walton
Buddy Walton
2 years ago

A.K maybe you can help I need to change non email enable user UPN to be firstname.lastname every thing I try does not work. This works but I can’t use it I need to take users from a csv file
Get-ADUser -Filter ‘Name -like “*”‘ -Server ‘<domain name>’ -SearchBase ‘<OU Path>’ -Properties UserPrincipalName| % {Set-ADUser $_ -UserPrincipalName ($_.Surname + ‘.’ + $_.GivenName + “<domainame>”)}

Joji
Joji
2 years ago

I got the solution, Thanks in advance

$ous = “OU=MENGEN,OU=DEMO,DC=demo,DC=it-koehler,DC=com”,“OU=SIGMARINGEN,OU=DEMO,DC=demo,DC=it-koehler,DC=com”
[boolean]$logonly = $false
[string] $csvuserLogfilePath = “D:\temp\UPN”
  
 [string] $csvuserLogfileDate = Get-Date -Format “yyyy-MM-dd-HH-mm”
 [string] $csvuserLogfileNamePrefix = “UPN-Before”
 [string] $csvuserLogfileName = $($csvuserLogfileNamePrefix + $csvuserLogfileDate + “.csv”)
 [string] $csvuserLogfile = $csvuserLogfilePath + “\” + $csvuserLogfileName

 [string] $csvuserLogfileNamePrefix = “UPN-Changed”
 [string] $csvuserLogfileName = $($csvuserLogfileNamePrefix + $csvuserLogfileDate + “.csv”)
 [string] $csvuserLogfilechanged = $csvuserLogfilePath + “\” + $csvuserLogfileName
  $dcfqdn = ((Get-ADDomainController).Hostname)
 Add-Content -Path $csvuserLogfile -Value “SamAccountName;UserPrincipalName;Mail”
 if($logonly -ne “$true”){
 Add-Content -Path $csvuserLogfilechanged -Value “SamAccountName;UserPrincipalName;Mail”
 }
foreach($ou in $ous){

  $users = (Get-ADUser -Server $dcfqdn -Filter * -Properties * -SearchBase “$ou”  | Where-Object {$_.mail -ne $null})
    foreach($user in $users){
        $attribute1 = $user | Select-Object samaccountname -ExpandProperty samaccountname
        $attribute2 = $user | Select-Object userprincipalname -ExpandProperty userprincipalname
        $attribute3 = $user | Select-Object mail -ExpandProperty mail
$attribute4 = ($attribute3 -Split’@’)[0]
          Add-Content -Path $csvuserLogfile -Value “$attribute1;$attribute2;$attribute3”
        
        if($logonly -ne “$true”){
        Write-Host “set UPN $attribute3 for user $attribute1” -ForegroundColor Green 
        Set-ADUser -Server “$dcfqdn” -Identity “$user” -UserPrincipalName “$attribute3”
Set-ADUser -Server “$dcfqdn” -Identity “$user” -SamAccountName “$attribute4”
        $changeduser = Get-ADUser -Server $dcfqdn -Identity “$user” -Properties mail | select samaccountname,userprincipalname,mail
        $change1 = $changeduser | Select-Object samaccountname -ExpandProperty samaccountname
        $change2 = $changeduser | Select-Object userprincipalname -ExpandProperty userprincipalname
        $change3 = $changeduser | Select-Object mail -ExpandProperty mail
        Add-Content -Path $csvuserLogfilechanged -Value “$change1;$change2;$change3”
         
         }
         
        
        }

  }

Joji
Joji
2 years ago

I would also like to update the SamAccount name with the same email id after removing the domain name

Last edited 2 years ago by Joji