This is a PowerShell script to find duplicate email addresses among any objects in Active Directory. Duplicates raise errors during synchronization with Azure AD or Office 365. All classes of objects are considered. The email addresses can be in any of the following attributes: userPrincipalName, mail, proxyAddresses, and msRTCSIP-PrimaryUserAddress.

The script first finds all objects in the Active Directory domain with any values assigned to any of the four attributes. Then the script evaluates all of the values. Any prefix, such as "SMTP:", "smtp:", or "sip:" is stripped away. Then the remaining values are compared to those in a hash table. If there is a match, the script outputs the value and the distinguished names of the conflicting objects, with the attribute where the value is found in parentheses. If no match is found, the value is added to the hash table.

 

For example, duplicates could result in output similar to the following:
Bash/shell
Edit|Remove
Duplicate value: jsmith@MyDomain.com 
    CN=Jim Smith,OU=West,DC=MyDomain,DC=com (proxyAddresses) 
    CN=Jane Smith,OU=East,DC=MyDomain,DC=com (UPN) 
Duplicate value: rwilson@MyDomain.com 
    CN=Ronald Wilson,OU=West,DC=MyDomain,DC=com (mail, UPN) 
    CN=Raymond Wilson,OU=North,DC=MyDomain,DC=com (UPN) 
 

 

If the duplicate appears in more than one attribute for an object, then both attributes are noted. The output can be redirected to a text file. It then is up to an administrator to correct the conflicts. The output has enough information to locate the conflicting objects, and the attributes with the duplicate values. The script follows.

 

 

 

PowerShell
Edit|Remove
# FindDuplIDs.ps1 
# Script to find objects with duplicates among the following AD attributes: 
# userPrincipalName, mail, msRTCSIP-PrimaryUserAddress, proxyAddresses 
# Version 1.0 - December 82018 
# Version 1.1 - March 12019 
#               Quote attribute with lDAPDisplayName msRTCSIP-PrimaryUserAddress. 
 
# Retrieve all objects where any of the attributes are assigned values. 
$Prop = @("userPrincipalName","mail","msRTCSIP-PrimaryUserAddress","proxyAddresses") 
$Filter = "(|(userPrincipalName=*)(mail=*)(msRTCSIP-PrimaryUserAddress=*)(proxyAddresses=*))" 
$Objects = Get-ADObject -LDAPFilter $Filter -Properties $Prop 
 
# Hash table of IDs. The key is the ID (the value of one of the 4 attributes), 
# the value is the DN of the objects with the value (and the attribute names). 
# The DNs in the value are separated by the "@" character. It is assumed that 
# no distinguished names have this character. 
$IDs = @{} 
 
# Loop through the objects. 
ForEach ($Object In $Objects) 
{ 
    # Retrieve attribute values. 
    $DN = $Object.distinguishedName 
    $UPN = $Object.userPrincipalName 
    $Mail = $Object.mail 
    $PrimAddr = $Object."msRTCSIP-PrimaryUserAddress" 
    $ProxyAddrs = $Object.proxyAddresses 
 
    # Check userPrincipalName. 
    If ($UPN) 
    { 
        # Check if this ID has been seen already. 
        If ($IDs.ContainsKey($UPN)) 
        { 
            # Duplicate ID, append to value. 
            $IDs[$UPN] = $IDs[$UPN] + "@$DN `(UPN)" 
        } 
        Else 
        { 
            # Add this ID to the hash table. 
            $IDs.Add($UPN, "$DN `(UPN)") 
        } 
    } 
    # Check mail. 
    If ($Mail) 
    { 
        # Only consider value after any colon character. 
        $Mail = ($Mail.Split(":"))[-1] 
        # Check if this ID has been seen already. 
        If ($IDs.ContainsKey($Mail)) 
        { 
            # Check for the current DN. 
            If ($IDs[$Mail] -Like "*$DN `(*") 
            { 
                # Add mail to the list of attributes for this DN. 
                $IDs[$Mail] = $IDs[$Mail].Replace("$DN `(","$DN `(mail,") 
            } 
            Else 
            { 
                # Duplicate ID, append to value. 
                $IDs[$Mail] = $IDs[$Mail] + "@$DN `(Mail)" 
            } 
        } 
        Else 
        { 
            # Add this ID to the hash table. 
            $IDs.Add($Mail, "$DN `(mail)") 
        } 
    } 
    # Check msRTCSIP-PrimaryUserAddress. 
    If ($PrimAddr) 
    { 
        # Only consider value after any colon character. 
        $PrimAddr = ($PrimAddr.Split(":"))[-1] 
        # Check if this ID has been seen already. 
        If ($IDs.ContainsKey($PrimAddr)) 
        { 
            # Check for the current DN. 
            If ($IDs[$PrimAddr] -Like "*$DN `(*") 
            { 
                # Add msRTCSIP-PrimaryUserAddress to the list of attributes for this DN. 
                $IDs[$PrimAddr] = $IDs[$PrimAddr].Replace("$DN `(","$DN `(msRTCSIP-PrimaryUserAddress,") 
            } 
            Else 
            { 
                # Duplicate ID, append to value. 
                $IDs[$PrimAddr] = $IDs[$PrimAddr] + "@$DN `(msRTCSIP-PrimaryUserAddress)" 
            } 
        } 
        Else 
        { 
            # Add this ID to the hash table. 
            $IDs.Add($PrimAddr, "$DN `(msRTCSIP-PrimaryUserAddress)") 
        } 
    } 
    # Check proxyAddresses. 
    If ($ProxyAddrs) 
    { 
        # Check each address in proxyAddresses. 
        ForEach ($Addr In $ProxyAddrs) 
        { 
            # Only consider value after any colon character. 
            $Addr = ($Addr.Split(":"))[-1] 
            # Check if this ID has been seen already. 
            If ($IDs.ContainsKey($Addr)) 
            { 
                # Check for the current DN. 
                If ($IDs[$Addr] -Like "*$DN `(*") 
                { 
                    # Add proxyAddresses to the list of attributes for this DN. 
                    $IDs[$Addr] = $IDs[$Addr].Replace("$DN `(","$DN `(proxyAddresses,") 
                } 
                Else 
                { 
                    # Duplicate ID, append to value. 
                    $IDs[$Addr] = $IDs[$Addr] + "@$DN `(proxyAddresses)" 
                } 
            } 
            Else 
            { 
                # Add this ID to the hash table. 
                $IDs.Add($Addr, "$DN `(proxyAddresses)") 
            } 
        } 
    } 
} 
 
# Enumerate all IDs. 
ForEach ($ID In $IDs.Keys) 
{ 
    $Values = $IDs[$ID].Split("@") 
    If ($Values.Count -gt 1) 
    { 
        "Duplicate ID: $ID" 
        ForEach ($Entry In $Values) 
        { 
            "    $Entry" 
        } 
    } 
}