391 Chapter 12. Replication Introduction Recipe 12.1. Determining if Two Domain Controllers Are in Sync Recipe 12.2. Viewing the Replication Status of Several Domain Controllers Recipe 12.3. Viewing Unreplicated Changes Between Two Domain Controllers Recipe 12.4. Forcing Replication from One Domain Controller to Another Recipe 12.5. Changing the Intra-Site Replication Interval Recipe 12.6. Changing the Inter-Site Replication Interval Recipe 12.7. Disabling Inter-Site Compression of Replication Traffic Recipe 12.8. Checking for Potential Replication Problems Recipe 12.9. Enabling Enhanced Logging of Replication Events Recipe 12.10. Enabling Strict or Loose Replication Consistency Recipe 12.11. Finding Conflict Objects Recipe 12.12. Viewing Object Metadata Introduction Replication is one of the most important and perhaps complex components of Active Directory. The infrastructure behind Active Directory replication, including the site topology, connection objects, and the KCC, was covered in Chapter 11 . This chapter focuses strictly on some of the tasks and processes associated with replicating data and checking replication health. For an in- depth overview of how replication works in Active Directory, I suggest reading Chapter 5 in Active Directory, Second Edition (O'Reilly). 392 Recipe 12.1 Determining if Two Domain Controllers Are in Sync 12.1.1 Problem You want to determine if two domain controllers are in sync and have no objects to replicate to each other. 12.1.2 Solution 12.1.2.1 Using a command-line interface By running the following two commands you can compare the up-to-dateness vector on the two DCs: > repadmin /showutdvec <DC1Name> <NamingContextDN> > repadmin /showutdvec <DC2Name> <NamingContextDN> The Windows 2000 version of repadmin used a different syntax to accomplish the same thing. Here is the equivalent syntax: > repadmin /showvector <NamingContextDN> <DC1Name> > repadmin /showvector <NamingContextDN> <DC2Name> 12.1.2.2 Using VBScript ' This code prints the up-to-dateness vector for the DCs defined in ' the array arrDCList for the naming context defined by strNCDN ' SCRIPT CONFIGURATION ' Set to the DN of the naming context you want to check the DCs against strNCDN = "<NamingContextDN>" ' e.g. dc=amer,dc=rallencorp,dc=com ' Enter 2 or more DCs to compare arrDCList = Array("<DC1Name>","<DC2Name>") ' END CONFIGURATION set objIadsTools = CreateObject("IADsTools.DCFunctions") for each strDC in arrDCList WScript.Echo "Replication partner USNs for " & strDC & ":" intUSN = objIadsTools.GetHighestCommittedUSN(Cstr(strDC),0) if intUSN = -1 then Wscript.Echo "Error retrieving USN: " & objIadsTools.LastErrorText WScript.Quit end if WScript.Echo vbTab & strDC & " = " & intUSN intRes = objIadsTools.GetReplicationUSNState(Cstr(strDC), _ Cstr(strNCDN),0,0) if intRes = -1 then Wscript.Echo "Error retrieving USNs: " & objIadsTools.LastErrorText WScript.Quit end if 393 for count = 1 to intRes WScript.Echo vbTab & objIadsTools.ReplPartnerName(count) & _ " = " & objIadsTools.ReplPartnerUSN(count) next WScript.Echo next 12.1.3 Discussion To determine if two or more DCs are in sync from a replication standpoint, you need to compare their up-to-dateness vectors. Each domain controller stores what it thinks is the highest update sequence number (USN) for every DC that replicates a naming context. This is called the up-to- dateness vector. If you want to compare DC1 and DC2, you'd first want to get the up-to-dateness vector for DC1 and compare DC1's highest USN against what DC2 thinks DC1's highest USN is. If they are different, then you can deduce that DC2 has not replicated all the changes from DC1 yet. Next, compare the reverse to see if DC1 is in sync with DC2. 12.1.4 See Also See IadsTools.doc in the Support Tools for more information on the IADsTools interface Recipe 12.2 Viewing the Replication Status of Several Domain Controllers 12.2.1 Problem You want to take a quick snap-shot of replication activity for one or more domain controllers. 12.2.2 Solution 12.2.2.1 Using a command-line interface The following command will show the replication status of all the domain controllers in the forest: > repadmin /replsum You can also use * as a wildcard character to view the status of a subset of domain controllers. The following command will display the replication status of only the servers that begin with the name dc-rtp: > repadmin /replsum dc-rtp* This command is only available with the Windows Server 2003 version of repadmin. 394 12.2.3 Discussion The new /replsum option in repadmin is a great way to quickly determine if there are any replication issues. This command should be your starting point if you suspect any replication problems. If you are running /replsum against a lot of domain controllers, you can use the /sort option to order the returned table output by any of the table columns. You can also use the /errorsonly option to display only the replication partners who are encountering errors. Recipe 12.3 Viewing Unreplicated Changes Between Two Domain Controllers 12.3.1 Problem You want to find the unreplicated changes between two domain controllers. 12.3.2 Solution 12.3.2.1 Using a graphical user interface 1. Open the Replication Monitor from the Support Tools (replmon.exe). 2. From the menu, select View Options. 3. On the General tab, check the box beside Show Transitive Replication Partners and Extended Data. 4. Click OK. 5. In the left pane, right-click on Monitored Servers and select Add Monitored Server. 6. Use the Add Monitored Server Wizard to add one of the domain controllers you want to compare (I'll call it dc1). 7. In the left pane, under the server you just added, expand the naming context that you want to check for unreplicated changes. 8. Right-click on the other domain controller you want to compare (I'll call it dc2) and select Check Current USN and Un-replicated Objects. 9. Enter credentials if necessary and click OK. 10. If some changes have not yet replicated from dc2 to dc1, a box will pop up that lists the unreplicated objects. 11. To find out what changes have yet to replicate from dc1 to dc2, repeat the same steps except add dc2 as a monitored server and check for unreplicated changes against dc1. 12.3.2.2 Using a command-line interface Run the following two commands to find the differences between two domain controllers. Use the /statistics option to view a summary of the changes: > repadmin /showchanges <DC1Name> <DC2GUID> <NamingContextDN> > repadmin /showchanges <DC2Name> <DC1GUID> <NamingContextDN> 395 The Windows 2000 version of repadmin has a different syntax to accomplish the same thing. Here is the equivalent syntax: > repadmin /getchanges <NamingContextDN> <DC1Name> <DC2GUID> > repadmin /getchanges <NamingContextDN> <DC2Name> <DC1GUID> 12.3.2.3 Using VBScript ' This code uses the IADsTools interface to print the unreplicated ' changes for the naming context defined by strNCDN for the DCs ' defined by strDC1Name and strDC2Name ' SCRIPT CONFIGURATION strNCDN = "<NamingContextDN>" ' e.g. dc=rallencorp,dc=com strDC1Name = "<DC1Name>" ' e.g. dc1.rallencorp.com strDC2Name = "<DC2Name>" ' e.g. dc2.rallencorp.com ' END CONFIGURATION set objIadsTools = CreateObject("IADsTools.DCFunctions") ' ' Have to get the GUIDs of both servers in order to identify ' the correct partner in the GetReplicationUSNState call ' strDC1GUID = objIadsTools.GetGuidForServer(Cstr(strDC1Name), _ Cstr(strDC1Name),0) strDC2GUID = objIadsTools.GetGuidForServer(Cstr(strDC2Name), _ Cstr(strDC2Name),0) ' ' Need to get what each DC thinks is the highest USN for the other ' The USN is needed in the call to GetMetaDataDifferences to return ' the unreplicated changes ' intRes = objIadsTools.GetReplicationUSNState(Cstr(strDC1Name), _ Cstr(strNCDN),0,0) if intRes = -1 then Wscript.Echo objIadsTools.LastErrorText WScript.Quit end if for count = 1 to intRes if strDC2GUID = objIadsTools.ReplPartnerGuid(count) then intDC2USN = objIadsTools.ReplPartnerUSN(count) end if next if intDC2USN = "" then WScript.Echo strDC2Name & " is not a replication partner with " & _ strDC1Name end if intRes = objIadsTools.GetReplicationUSNState(Cstr(strDC2Name), _ Cstr(strNCDN),0,0) if intRes = -1 then Wscript.Echo objIadsTools.LastErrorText WScript.Quit end if for count = 1 to intRes if strDC1GUID = objIadsTools.ReplPartnerGuid(count) then 396 intDC1USN = objIadsTools.ReplPartnerUSN(count) end if next if intDC2USN = "" then WScript.Echo strDC1Name & " is not a replication partner with " & _ strDC2Name end if ' ' Now that we have retrieved the highest USN for both partners, ' the GetMetaDataDifferences method will return what needs to be ' replicated ' intRes = objIadsTools.GetMetaDataDifferences(Cstr(strDC1Name), _ Cstr(intDC1USN), _ Cstr(strNCDN),0) if intRes = -1 then Wscript.Echo objIadsTools.LastErrorText WScript.Quit end if WScript.Echo "Data on " & strDC1Name & " but not " & strDC2Name & ":" for count = 1 to intRes WScript.Echo count & ". " & _ objIadsTools.MetaDataDifferencesObjectDN(count) WScript.Echo vbTab & " Attribute: " & _ objIadsTools.MetaDataDifferencesAttribute(count) WScript.Echo vbTab & " Write time: " & _ objIadsTools.MetaDataDifferencesLastWriteTime(count) WScript.Echo vbTab & " Orig Server: " & _ objIadsTools.MetaDataDifferencesOrigServer(count) WScript.Echo vbTab & " Orig USN: " & _ objIadsTools.MetaDataDifferencesOrigUSN(count) next WScript.Echo intRes = objIadsTools.GetMetaDataDifferences(Cstr(strDC2Name), _ Cstr(intDC2USN), _ Cstr(strNCDN), 0) if intRes = -1 then Wscript.Echo objIadsTools.LastErrorText WScript.Quit end if WScript.Echo "Data on " & strDC2Name & " but not " & strDC1Name & ":" for count = 1 to intRes WScript.Echo count & ". " & _ objIadsTools.MetaDataDifferencesObjectDN(count) WScript.Echo vbTab & " Attribute: " & _ objIadsTools.MetaDataDifferencesAttribute(count) WScript.Echo vbTab & " Write time: " & _ objIadsTools.MetaDataDifferencesLastWriteTime(count) WScript.Echo vbTab & " Orig Server: " & _ objIadsTools.MetaDataDifferencesOrigServer(count) WScript.Echo vbTab & " Orig USN: " & _ objIadsTools.MetaDataDifferencesOrigUSN(count) next 397 12.3.3 Discussion All three solutions show how to display the current unreplicated changes between two domain controllers. The repadmin /showchanges command has several additional options you can use to display the changes, including saving the output to a file for later comparison. Also, with the /statistics option, you can view a summary of the changes. 12.3.4 See Also See IadsTools.doc in the Support Tools for more information on the IADsTools interface Recipe 12.4 Forcing Replication from One Domain Controller to Another 12.4.1 Problem You want to force replication between two partners. 12.4.2 Solution 12.4.2.1 Using a graphical user interface 1. Open the Active Directory Sites and Services snap-in. 2. Browse to the NTDS Setting object for the domain controller you want to replicate to. 3. In the right pane, right-click on the connection object to the domain controller you want to replicate from and select Replicate Now. 12.4.2.2 Using a command-line interface The following command will perform a replication sync of the naming context specified by <NamingContextDN> from <DC2Name> to <DC1Name>: > repadmin /replicate <DC1Name> <DC2Name> <NamingContextDN> The Windows 2000 version of repadmin has a different syntax to accomplish the same thing. Here is the equivalent syntax: > repadmin /sync <NamingContextDN> <DC1Name> <DC2GUID> 12.4.2.3 Using VBScript ' This code initiates a replication event between two DCs ' for a naming context ' SCRIPT CONFIGURATION strDC1Name = "<DC1Name>" ' e.g. dc1 strDC2Name = "<DC2Name>" ' e.g. dc2 strNamingContextDN = "<NamingContextDN>" ' e.g. dc=rallencorp,dc=com 398 ' END CONFIGURATION set objIadsTools = CreateObject("IADsTools.DCFunctions") intRes = objIadsTools.ReplicaSync(Cstr(strDC1Name),_ Cstr(strNamingContextDN),_ Cstr(strDC2Name), 0, 0) if intRes = -1 then Wscript.Echo "Error: " & objIadsTools.LastErrorText else WScript.Echo "Replication intitiated from " & strDC2Name & _ " to " & strDC1Name end if 12.4.3 Discussion Each solution shows how to replicate all unreplicated changes from a source domain controller to a destination domain controller. This sync is one way. If you want to ensure that both domain controllers are in sync, you'll need to follow the same directions except swap the domain controllers. With repadmin you can replicate a single object instead of any unreplicated object in a naming context by using the /replsingleobj option. This option is only available with the Windows Server 2003 version of repadmin. 12.4.4 See Also Recipe 12.3 for viewing unreplicated changes between two domain controllers, MS KB 232072 (Initiating Replication Between Active Directory Direct Replication Partners), and see IadsTools.doc in the Support Tools for more information on the IADsTools interface Recipe 12.5 Changing the Intra-Site Replication Interval 12.5.1 Problem You want to change the number of seconds that a domain controller in a site waits before replicating within the site. 12.5.2 Solution 12.5.2.1 Using a graphical user interface 1. Run regedit.exe from the command line or Start Run. 2. Expand HKEY_LOCAL_MACHINE SYSTEM CurrentControlSet Services NTDS Parameters. 399 3. If a value entry for Replicator notify pause after modify (secs) does not exist, right-click on Parameters and select New DWORD Value. For the name, enter: Replicator notify pause after modify (secs). 4. Double-click on the value and enter the number of seconds to wait before notifying intra- site replication partners. 5. Click OK. 12.5.2.2 Using a command-line interface With the following command, change <NumSeconds> to the number of seconds to set the intra- site replication delay to: > reg add HKLM\System\CurrentControlSet\Services\NTDS\Parameters /v "Replicator[RETURN] notify pause after modify (secs)" /t REG_DWORD /d <NumSeconds> 12.5.2.3 Using VBScript ' This code sets the intra-site delay interval ' SCRIPT CONFIGURATION strDC = "<DomainControllerName>" ' DC you want to configure intNumSeconds = <NumSeconds> ' Time in seconds to delay ' END CONFIGURATION const HKLM = &H80000002 strNTDSReg = "SYSTEM\CurrentControlSet\Services\NTDS\Parameters" set objReg = GetObject("winmgmts:\\" & strDC & _ "\root\default:StdRegProv") objReg.SetDWORDValue HKLM, strNTDSReg, _ "Replicator notify pause after modify (secs)", _ intNumSeconds WScript.Echo "Intra-site replication delay set to " & intNumSeconds 12.5.3 Discussion After a change has been made to a domain controller's local copy of Active Directory, it waits for a period of time before sending change notification requests to its intra-site replication partners. The default delay on Windows 2000 domain controllers is five minutes. For Windows Server 2003, the default delay has been changed to 15 seconds. You can customize this notification delay by changing the registry value, Replicator notify pause after modify (secs), on the domain controllers, as described in the Solution section. If you are changing this setting on Windows 2000 domain controllers, Microsoft recommends removing it after upgrading to Windows Server 2003 in order to utilize the new default of 15 seconds. 12.5.4 See Also MS KB 214678 (How to Modify the Default Intra-Site Domain Controller Replication Interval) 400 Recipe 12.6 Changing the Inter-Site Replication Interval 12.6.1 Problem You want to set the schedule for replication for a site link. 12.6.2 Solution These solutions assume the IP transport, but the SMTP transport could be used as well. 12.6.2.1 Using a graphical user interface 1. Open the Active Directory Sites and Services snap-in. 2. Expand the Inter-Site Transport container. 3. Click on the IP container. 4. In the right pane, double-click on the site link you want to modify the replication interval for. 5. Enter the new interval beside Replicate every. 6. Click OK. 12.6.2.2 Using a command-line interface To change the replication interval, create an LDIF file named set_link_rep_interval.ldf with the following contents: dn: cn=<LinkName>,cn=ip,cn=Inter-Site Transports,cn=sites, cn=configuration,<ForestRootDN> changetype: modify replace: replInterval replInterval: <NewInterval> - then run the following command: > ldifde -v -i -f set_link_rep_interval.ldf 12.6.2.3 Using VBScript ' This code sets the replication interval for a site link ' SCRIPT CONFIGURATION strLinkName = "<LinkName>" ' cn of the link you want to configure intNewInterval = <NewInterval> ' replication interval in minutes ' END CONFIGURATION set objRootDSE = GetObject("LDAP://RootDSE") set objLink = GetObject("LDAP://cn=" & strLinkName & _ ",cn=IP,cn=Inter-site Transports,cn=sites," & _ objRootDSE.Get("configurationNamingContext") ) . replicating data and checking replication health. For an in- depth overview of how replication works in Active Directory, I suggest reading Chapter 5 in Active Directory, Second Edition (O'Reilly) controller's local copy of Active Directory, it waits for a period of time before sending change notification requests to its intra-site replication partners. The default delay on Windows 2000 domain. the Windows Server 2003 version of repadmin. 12.4.4 See Also Recipe 12.3 for viewing unreplicated changes between two domain controllers, MS KB 232072 (Initiating Replication Between Active