Hello All

I was recently working on a project to migrate users from legacy domain to a primary domain. One of the many challenges is finding conflicting UPN between the two domains. UPN  (User-Principal-Name) is an Internet-style login name for a user based on the Internet standard RFC 822. The UPN is shorter than the distinguished name and easier to remember. This should map to the user email name.

The script will search the source domain and the target domain looking for the same UPN prefix.  For each user object, we are gathering: SamAccountName, UserPrincipalName, Initials, FirstName, and SN. Each user attribute is assigned S or T  SamAccountName, UserPrincipalName, Initials, FirstName, and SN for matching and exporting.

Depending on if we have an export of the source domain user UPN in csv format, that data can be imported.  Otherwise we could use an mounted PSDrive to gather the data from the source domain when running the script. I will cover New-PSDrive in more detail, in a later blog.

$UserSearch = Import-CSV "C:\Working\input\upn.csv" 
$UserSearch = Get-ADUser -Filter 'enabled -eq $true'

The script uses OUT-File with predefined headers.

$FN_LN_Match`t$FN_LN_I_Match`t$UPN_Match`t$SAM_Match`t$Ssamaccountname`t$Tsamaccountname`t$Suserprincipalname`t$Tuserprincipalname`t$SFirstname`t$TFirstname`t$SInitials`t$TInitials`t$SLastname`t$Tlastname`t$Tname” | Out-File $UserOutFile -encoding ASCII -append

Now for some code.

$usersearch | ForEach-Object {
      $EMP = $_.UserPrincipalName
      $EMP =($emp.split("@"))[0]
      $ObjFilter = "(&(objectCategory=User)(UserPrincipalName=$EMP@*))"
      $objSearch = New-Object System.DirectoryServices.DirectorySearcher
      $objSearch.PageSize = 15000
      $objSearch.Filter = $ObjFilter
 #Search objects in the Source Domain
      $objSearch.SearchRoot = "LDAP://DC=Your,DC=Source,DC=Domain"
      $AllObj = $objSearch.FindAll()
 foreach ($Obj in $AllObj)
       { $objItemS = $Obj.Properties
       $Ssamaccountname = $objItemS.samaccountname
       $Suserprincipalname = $objItemS.userprincipalname
       $SupnPrefix = ($Suserprincipalname.split("@"))[0]
       $SInitials = $objItemS.initials
       $SFirstname = $objItemS.givenname
       $SLastname = $objItemS.sn

The code is searching the source domain via LDAP:  with the filter “USER” object and “UPN@*” where UPN is current user object.

$ObjFilter = "(&(objectCategory=User)(UserPrincipalName=$EMP@*))"

Now lets search the Target domain (Primary).

$objSearch.SearchRoot = "LDAP://DC=your,DC=Target,DC=Domain"
 $AllObj = $objSearch.FindAll()
 foreach ($Obj in $AllObj)
      { $objItemT = $Obj.Properties
        $Tsamaccountname = $objItemT.samaccountname
        $Tname = $objItemT.name
        $Tuserprincipalname = $objItemT.userprincipalname
        $TupnPrefix = ($Tuserprincipalname.split("@"))[0]
        $TInitials = $objItemT.initials
        $TFirstname = $objItemT.givenname
        $TLastname = $objItemT.sn

The $ObjFilter is still defined from above.

Additional code is used to match the records.

#matching for output
 if ($SFirstname -eq $TFirstname -and $TLastname -eq $SLastname){
 $FN_LN_Match = 'Match' 
 } else {
 $FN_LN_Match = 'noMatch'
 if ($SFirstname -eq $TFirstname -and $TInitials-eq $SInitials -and $TLastname -eq $SLastname){
 $FN_LN_I_Match = 'Match' 
 } else {
 $FN_LN_I_Match = 'noMatch'
 if ($SFirstname -eq $TFirstname -and $TLastname -eq $SLastname -and $TupnPrefix -eq $SupnPrefix){
 $UPN_Match = 'Match' 
 } else {
 $UPN_Match = 'noMatch'
 if ($Tsamaccountname -eq $Ssamaccountname ){
 $SAM_Match = 'Match' 
 } else {
 $SAM_Match = 'noMatch'


That’s about it for now!

About the Author: steve bowman

Three Minutes For A More Secure & Efficient Infrastructure

Short and to the point, Steve’s Email Blasts give you endpoint management tips, tricks, and news in three minutes or less email read-time, guaranteed.

Model says no to spam. Privacy Policy

Model Technology Solutions

Model Technology Solutions is a small but mighty band of infrastructure experts. We’ve helped companies in diverse industries to modernize and automate their infrastructures through effectively managing their Microsoft endpoint suite.

With us on your team, you’ll watch your security and compliance go up and your IT team’s costs (and headaches) go down. You’ll relax in knowing that your endpoints will be secure and online when your users need them most. And you’ll finally get back to your most-important tasks.

Model Technology Solutions
12125 Woodcrest Executive Drive, Ste. 204 Creve Coeur, MO 63141

Phone: (314) 254-4138
General Inquiries: model@model-technology.com
Sales and Quotes: sales@model-technology.com