If you are familiar with the errors generated from AADSync or DirSync that tell you about a duplicate object in your environment, you understand the pain associated with sometimes trying to track down which objects have the conflicting values.  Our tool, IDFix, can identify and help remediate many of these issues; however, there are some use cases that it doesn't identify yet, which is a gap this tool aims to fill.

Using the duplicate value referenced from the AADSync or DirSync Connector (or from running csexport), run this script to locate the errant objects.  Depending on your search parameters, this will query the default AD attributes, Exchange attributes, or SIP attributes that can cause sync to report a conflict.

For more information on this tool, check out the associated blog at https://undocumented-features.com/2016/10/17/finding-duplicate-objects-in-active-directory/.

* Updates

- Allow searching for full or partial x500 address

* Previous updates 2016-10-27
- Fixed an issue with $FormatEnumerationLimit.
- The output now highlights the matching values, making it easier to locate conflicting attributes
- Detect if schema contains SIP and Exchange attributes
- Due to an issue with Partial Matching, replaced -LDAPFilter with -Filter parameter.  The original -LDAPFilter syntax is still available if you want to do partial matching via the new -LDAPStyle parameter.

 

PowerShell
Edit|Remove
<# 
.SYNOPSIS 
Find objects with duplicate values across multiple 
attributes. 
 
.DESCRIPTION 
This script can be used to find multiple objects in a 
forest that contain duplicate values.   
 
Object types searched: 
- user 
- group 
- contact 
 
Default Attributes searched: 
- userPrincipalName 
- mail 
 
Exchange Attributes searched: 
- proxyAddresses 
- targetAddress 
 
SIP Attributes searched: 
- msRTCSIP-PrimaryUserAddress 
 
.PARAMETER Address 
Object address expressed as a userPrincipalName or 
email address. 
 
.PARAMETER Autodetect 
Detect which schema classes to query automatically. 
 
.PARAMETER Credential 
Optionally specify a credential to be used. 
 
.PARAMETER IncludeExchange 
Include Exchange attributes (must have Active Directory  
schema extended for Exchange). 
 
.PARAMETER IncludeSIP 
Include SIP attributes (must have Active Directory schema 
extended for a SIP product, such as Live Communications 
Server, Office Communications Server, Lync Server, or 
Skype for Business Server). 
 
.PARAMETER LDAPStyle 
Perform older LDAPFilter style matching (which will include 
partial matches. 
 
.PARAMETER OutputColor 
Specify output color for match highlighting. 
 
.EXAMPLE 
.\Find-DuplicateValues.ps1 -Credential (Get-Credential) -Address john@contoso.com -IncludeExchange 
Prompt for credentials and search all domains in forest for default and Exchange attributes that contain john@contoso.com. 
 
.EXAMPLE 
.\Find-DuplicateValues.ps1 -Address john@contoso.com -IncludeExchange -IncludeSIP 
Search all domains in forest for default, Exchange, and SIP attributes that contain john@contoso.com. 
 
.EXAMPLE 
.\Find-DuplicateValues.ps1 -Credential $cred -Address john@contoso.com -IncludeSIP 
Search all domains in forest for default and SIP attributes using saved credential object $cred. 
 
.LINK 
https://gallery.technet.microsoft.com/Find-Duplicate-Values-in-6b012059 
 
.NOTES 
 
2018-04-16 - Update to search for duplicate x500 patterns. 
           - Update to perform better in large environments. 
2016-10-26 - Update for $FormatEnumeration parameter. 
2016-10-17 - The output now highlights the matching values, making it easier to locate conflicting attributes 
             - Detect if schema contains SIP and Exchange attributes 
             - Due to an issue with Partial Matching, replaced -LDAPFilter with -Filter parameter.   
             The original -LDAPFilter syntax is still available if you want to do partial matching  
             via the new -LDAPStyle parameter. 
2016-10-01 - Original release. 
 
All envrionments perform differently. Please test this code before using it 
in production. 
 
THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY  
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE  
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR 
PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR RESULTS FROM THE USE OF  
THIS CODE REMAINS WITH THE USER. 
 
Author: Aaron Guilmette 
        aaron.guilmette@microsoft.com 
#>