Bulk AD UPN change

#========================================================================
# Created by:   Ramez Wanis
# The script fix the issue with mismatching User principal name between office 365 and local AD in the situation with hybrid exchange usage 
#========================================================================

Clear-Host
$ScriptPath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent)
$FilePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -Leaf)
$FilePath =$FilePath.Replace(".ps1","")
$LogFileName = $ScriptPath + "\ +$FilePath+ ".Log"
$ErrorLogFileName = $ScriptPath + "\ +$FilePath+ "_Error.Log"
$list = $ScriptPath + "\ + $FilePath + ".txt"
$ResultList = $ScriptPath + "\ + $FilePath + ".csv"

$UPNsuffix = "YourCompany.mail.onmicrosoft.com" # must change this in-order to work

Function Logme()
{param($Text)
(Get-Date -Format "MM/dd/yyyy HH:mm:ss ") + $Text | Out-File $LogFileName -Append
Write-Host (Get-Date -Format "MM/dd/yyyy HH:mm:ss ") + $Text
}

Import-Module ActiveDirectory -Verbose:$false  -WarningAction SilentlyContinue -ErrorAction SilentlyContinue

$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -Verbose:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue

Connect-MsolService -Credential $UserCredential

$o365list = Get-MsolUser -all | select DisplayName,ImmutableId,LiveId,ObjectId,UserPrincipalName,ProxyAddresses

foreach($o365usr in $o365list)
{
$usrname = $o365usr.displayname
$Adusr = Get-ADUser -Filter {Displayname -like $usrname} -Properties samaccountname, emailaddress,UserPrincipalName,mailNickname | select samaccountname, emailaddress,UserPrincipalName,mailNickname
$O365UPN = $o365usr.UserPrincipalName
$O365nick = $O365UPN.Split(1,"@")[0]
$AdUPN  =$Adusr.UserPrincipalName
$Adnick =$Adusr.mailNickname
if ($Adusr -eq "" -or $null){
Logme -Text ("user not found: " + $O365UPN)
}else{
if ($AdUPN -ne $null){
if ($AdUPN -is [system.Array]){
$flag=$false
foreach($user in $Adusr){
#Write-Host $user.UserPrincipalName
foreach($email in $o365usr.ProxyAddresses){
if ($email.Substring(5) -eq $user.emailaddress){
$AdUPN = $user.UserPrincipalName
#write-host $user.UserPrincipalName
$flag=$true
break
}
}
if ($flag -eq $true){
break
}
}
}
if($AdUPN -ne $O365UPN -and $AdUPN -isnot [system.Array]) {
Logme -Text ("--------------Change UPN--------------")
Logme -Text ("Name: " + $o365usr.DisplayName)
Logme -Text ("O365 UPN: " + $O365UPN)
Logme -Text ("AD UPN: " + $AdUPN)
#Logme -Text ("user AD Email : " + $Adusr.emailaddress)
$tmpupn="$O365nick@$UPNsuffix"
$status = Set-MsolUserPrincipalName -UserPrincipalName $O365UPN -NewUserPrincipalName $tmpupn -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
if ($status -ne $null){
$status = Set-MsolUserPrincipalName -UserPrincipalName $tmpupn -NewUserPrincipalName $AdUPN -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
if ($status -ne $null){
logme -Text ("UPN change completed successful")
}
$chkChange= Get-MsolUser -UserPrincipalName $O365UPN  -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
if ($chkChange.UserPrincipalName -ne "" -and $chkChange.UserPrincipalName -eq $O365UPN ){
logme -Text ("Error changing User UPN")
Write-Host "Set-MsolUserPrincipalName -UserPrincipalName $tmpupn -NewUserPrincipalName $AdUPN"
}
}else{
Logme -Text ("Error: Set command to default domain failed")
}
}
}else{
#logme -Text ("User: " + $Adusr.samaccountname + " UPN is NULL" )
}
}
}
Remove-PSSession $Session