Rename UPN in AD, AAD and Update Primary SMTP

Hi,
I am starting to use more PowerShell for everyday jobs and put together this script to do 3 things. Wondered if there was advice on tidying this up to improve it (and my knowledge along the way!).

Any help or advice appreciated.

# Get AD Objects in Scope

$Users = Import-CSV C:\Temp\TestAAD.csv

# Rename UPN in AD

$Users | foreach-object {

Write-host “Changing UPN for user $($_.SamAccountName) to $($_.NewUserPrincipalName)” -Foregroundcolor Green

Set-ADUser -identity $_.SamAccountName -userprincipalname $_.Newuserprincipalname }

# Pause for 3 Seconds
Start-Sleep -Seconds 3

# Rename Primary SMTP Address

$Users | foreach-object {

Write-host “Changing PrimarySMTP for user $($_.UserPrincipalName) to $($_.PrimarySmtpAddress)” -Foregroundcolor Green

Set-RemoteMailbox -Identity $_.UserPrincipalName -PrimarySMTPAddress $_.PrimarySMTPAddress }

# Pause for 3 Seconds
Start-Sleep -Seconds 3

# Rename UPN in AAD

$Users | ForEach-Object {

Write-host “Changing UPN for user $($_.UserPrincipalName) to $($_.NewUserPrincipalName)” -Foregroundcolor Green

Set-MsolUserPrincipalName -UserPrincipalName $_.UserPrincipalName -NewUserPrincipalName $_.Newuserprincipalname 
}

tp44794,
Welcome back to the forum. :wave:t4: … long time no see.

You may start with reading

or this:

Some short recommendations:

  • Do not over comment.
    Even for human beeings not knowing PowerShell it’d some kind of obvious that
Start-Sleep -Seconds 3

does a

# Pause for 3 Seconds
  • Do not use Write-Host
    Write-Host Considered Harmful | Jeffrey Snover's blog

  • Do not post unnecessary white space or empty lines. It makes your code harder to read

  • Format your code nicely. Use indentations. Add line breaks after pipe symbols to reduse the length of your code lines.

  • Do not iterate more than once over a given array if it’s not necessary.

Thank you Olaf, much appreciated. Ill take a look at the guides :slight_smile:

Olaf has linked you to a number of resources concerning style and I have nothing to add there.
What I’m wondering is, do you not sync your local users with AAD via an AAD-connect or similar?

If so I would be very surprised if you needed the second part of the script as the sync really should take care of the changed UPN.
Actually I would expect the Set-MSOLUserPrincipalName to fail as the user should be managed from the local AD.

Hi,

Yes AAD Connect is used and the 2nd step does make the change as required.

Testing in my lab, the UPN updated fine with a sync, however i believe there is an issue with UPN not updating for licensed objects in M365 which means you need to change the UPN manually in AAD.

OK.
I’ve never needed to update that attribute before, so I’ll accept that may be needed.

A couple of things I’d personally look at in your script would be adding a bit of error handling. I would wrap the Set-RemoteMailbox and Set-MSOLUserPrincipalName lines in a try/catch so I could catch and log any users that may need manual intervention.

I would probably also force a delta sync in AAD connect and add a longer sleep before running the second ForEach-Object, so you don’t risk clashing between the changes from your script and the sync.

And just a Heads-Up. The MS OnLine module is deprecated. While it still works you should probably be looking at moving scripts to the MS Graph module instead.

Thank you sir.

The feedback from you both is exactly what i am looking for to improve moving forward :slight_smile:

Ill take a look at error handling next…