531 ' First find the NTDS Settings object for the server ' strBase = "<LDAP://cn=Sites," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=server)(cn=" & strServer & "));" strAttrs = "cn,distinguishedName;" strScope = "subtree" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for server " & strServer WScript.Quit else objRS.MoveLast strServerDN = "cn=NTDS Settings," & _ objRS.Fields("distinguishedName").Value ' Make sure the NTDS Settings object actually exists set objNTDSDSA = GetObject("LDAP://" & strServerDN) Wscript.Echo "Found server: " WScript.Echo strServerDN Wscript.Echo end if ' ' Now need to find the crossRef object for the application partition ' strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)" & _ "(dnsRoot=" & strAppPart & "));" strAttrs = "cn,distinguishedName;" strScope = "onelevel" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for application partition " & _ strAppPart WScript.Quit else objRS.MoveLast set objAppPart = GetObject("LDAP://" & _ objRS.Fields("distinguishedName").Value ) Wscript.Echo "Found app partition: " WScript.Echo objRS.Fields("distinguishedName").Value WScript.Echo end if ' ' Lastly, either add or remove the replica server ' if boolAdd = TRUE then objAppPart.PutEx ADS_PROPERTY_APPEND, "msDS-NC-Replica-Locations", _ Array(strServerDN) objAppPart.SetInfo WScript.Echo "Added server to replica set" else 532 objAppPart.PutEx ADS_PROPERTY_DELETE, "msDS-NC-Replica-Locations", _ Array(strServerDN) objAppPart.SetInfo WScript.Echo "Removed server from replica set" end if 17.3.3 Discussion When you initially create an application partition, there is only one domain controller that hosts the application partition, namely the one you created the application partition on. You can add any other domain controllers in the forest as replica servers assuming the domain controllers are running Windows Server 2003. The list of replica servers is stored in the msDS-NC-Replica- Locations attribute on the crossRef object for the application partition in the Partitions container. That attribute contains the distinguished name of each replica server's nTDSDSA object. To add a replica server, simply add the DN of the new replica server. To remove a replica server, remove the DN corresponding to the server you want to remove. Behind the scene, the Knowledge Consistency Checker (KCC) gets triggered anytime there is a change to that attribute and will either cause the application partition to get replicated to the target domain controller or will remove it from the target domain controller. When a domain controller is demoted, it will automatically remove itself as a replica server for any application partitions it replicated. 17.3.4 See Also Recipe 17.4 for finding the replica servers for an application partition and MS KB 322669 (HOW TO: Manage the Application Directory Partition and Replicas in Windows Server 2003) Recipe 17.4 Finding the Replica Servers for an Application Partition 17.4.1 Problem You want to find the replica servers for an application partition. 17.4.2 Solution 17.4.2.1 Using a graphical user interface 1. Open ADSI Edit. 2. Connect to the configuration naming context of the forest the application partition is in, if it is not already present in the left pane. 3. Expand the configuration naming context and click on the Partitions container. 4. In the right pane, right-click on the crossRef object that represents the application partition and select Properties. 5. Under Attributes, select the msDS-NC-Replica-Locations attribute. 17.4.2.2 Using a command-line interface 533 > ntdsutil "dom man" conn "co to se <DomainControllerName>" q "list nc replicas[RETURN] <AppPartitionDN>" q q 17.4.2.3 Using VBScript ' This code displays the DN of each domain controller's ' nTDSDSA object that is a replica server for the ' specified app partition ' SCRIPT CONFIGURATION ' Fully qualified DNS name of app partition strAppPart = "<AppPartitionFQDN>" ' e.g. apps.rallencorp.com ' END CONFIGURATION set objRootDSE = GetObject("LDAP://RootDSE") strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)(dnsRoot=" & strAppPart & "));" strAttrs = "msDS-NC-Replica-Locations;" strScope = "onelevel" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for application partition " & _ strAppPart WScript.Quit else objRS.MoveLast if objRS.Fields("msDS-NC-Replica-Locations").Properties.Count > 0 then Wscript.Echo "There are no replica servers for app partition " & _ strAppPart else Wscript.Echo "Replica servers for app partition " & strAppPart & ":" for each strNTDS in objRS.Fields("msDS-NC-Replica-Locations").Value WScript.Echo " " & strNTDS next end if end if 17.4.3 Discussion The list of replica servers for an application partition is stored in the multivalued msDS-NC- Replica-Locations attribute on the crossRef object for the application partition. This object is located in the Partitions container in the configuration naming context. 17.4.4 See Also Recipe 17.3 for adding and removing replica servers 534 Recipe 17.5 Finding the Application Partitions Hosted by a Server 17.5.1 Problem You want to find the application partitions that a particular server replicates. Before you decommission a server, it is good to check to see if it hosts any application partitions and if so, add another replica server to replace it. 17.5.2 Solution 17.5.2.1 Using a graphical user interface 1. Open LDP. 2. From the menu, select Connection Connect. 3. For Server, enter the name of a DC. 4. For Port, enter 389. 5. Click OK. 6. From the menu, select Connection Bind. 7. Enter a user and password with the necessary credentials. 8. Click OK. 9. From the menu, select Browse Search. 10. For BaseDN, type the DN of the Partitions container (e.g., cn=partitions,cn=configuration,dc=rallencorp, dc=com). 11. For Filter, enter: 12. (&(objectcategory=crossRef)(systemFlags:1.2.840.113556.1.4.803:=5) 13. (msDS-NC-Replica-Locations=cn=NTDS Settings,cn=<DomainControllerName>, cn=servers,cn=<SiteName>,cn=sites, cn=configuration,<ForestDN>)) 14. For Scope, select One Level. 15. Click the Options button. 16. For Attributes, type dnsRoot. 17. Click OK. 18. Click Run. 17.5.2.2 Using a command-line interface Use the following command to find all of the application partitions hosted by a domain controller. To run this command, you need the distinguished name of the forest root domain ( <ForestDN>), the common name of the DC's server object (<DomainControllerName>), and the common name of the site object the server is in (<SiteName>). > dsquery * "cn=partitions,cn=configuration,<ForestDN>" -scope onelevel - attr[RETURN] dnsRoot -filter "(&(objectcategory=crossRef)(systemFlags:1.2.840.113556.1.4.803:=5)[RETURN] (msDS-NC-Replica-Locations=cn=NTDS Settings,cn=<DomainControllerName>,[RETURN] 535 cn=servers,cn=<SiteName>,cn=sites, cn=configuration,<ForestDN>))" 17.5.2.3 Using VBScript ' This code finds the application partitions hosted by the specified server. ' SCRIPT CONFIGURATION ' Hostname of server to add as replica for app partition. ' This needs to match the common name for the DC's server object. strServer = "<DomainControllerName>" ' e.g. dc01 ' END CONFIGURATION ' ' First need to find the NTDS Settings object for the server ' set objRootDSE = GetObject("LDAP://RootDSE") strBase = "<LDAP://cn=Sites," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=server)(cn=" & strServer & "));" strAttrs = "cn,distinguishedName;" strScope = "subtree" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for server " & strServer WScript.Quit else objRS.MoveLast strServerDN = "cn=NTDS Settings," & _ objRS.Fields("distinguishedName").Value Wscript.Echo "Found server object: " WScript.Echo strServerDN Wscript.Echo end if ' ' Find the crossRef objects that are hosted by the server ' strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)" & _ "(msDS-NC-Replica-Locations=" & strServerDN & "));" strAttrs = "nCName;" strScope = "onelevel" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount = 0 then WScript.Echo "Server " & strServer & _ " does not host any application partitions" WScript.Quit else Wscript.Echo "App partitions hosted by server " & strServer & ": " objRS.MoveFirst while not objRS.EOF WScript.Echo " " & objRS.Fields("nCName").Value objRS.MoveNext wend 536 end if 17.5.3 Discussion As described in Recipe 17.3 and Recipe 17.4, the msDS-NC-Replica-Locations attribute on crossRef objects contains the list of replica servers for a given application partition. Each of the solutions illustrates how to perform a query using this attribute to locate all of the application partitions a particular domain controller is a replica server for. For the GUI and CLI solutions, you need to know the distinguished name of the nTDSDSA object for the target domain controller. The VBScript solution tries to dynamically determine the distinguished name given a server name. 17.5.4 See Also Recipe 17.4 for finding the replica servers for an application partition Recipe 17.6 Verifying Application Partitions Are Instantiated on a Server Correctly 17.6.1 Problem You want to verify that an application partition is instantiated on a replica server. After you add a domain controller as a replica server for an application partition, the data in the application partition needs to fully replicate to that domain controller before it can be used on that domain controller. 17.6.2 Solution 17.6.2.1 Using a command-line interface Use the following command to determine if there are any problems with application partitions on a domain controller: > dcdiag /test:checksdrefdom /test:verifyreplicas /test:crossrefvalidation /s:[RETURN] <DomainControllerName> These tests are valid only with the Windows Server 2003 version of dcdiag. 17.6.3 Discussion The dcdiag CheckDSRefDom, VerifyReplicas, and CrossRefValidation tests can help determine if an application partition has been instantiated on a server and if there are any problems with it. Here is the dcdiag help information for those three tests: 537 CrossRefValidation This test looks for cross-referencess that are in some way invalid. CheckSDRefDom This test checks that all application directory partitions have appropriate security descriptor reference domains. VerifyReplicas This test verifies that all application directory partitions are fully instantiated on all replica servers. Another way you can check to see if a certain application partition has been instantiated on a domain controller yet is to look at the msDS-HasInstantiatedNCs attribute for the server's nTDSDSA object. That attribute has DN with Binary syntax and contains a list of all the application partitions that have been successfully instantiated on the server. Unfortunately, tools such as ADSI Edit and dsquery do not interpret DN with Binary attributes correctly, but it can be viewed with LDP. Recipe 17.7 Setting the Replication Notification Delay for an Application Partition 17.7.1 Problem Two replication-related settings that you can customize for application partitions (or any naming context for that matter) include the first and subsequent replication delay after a change to the partition has been detected. The first replication delay is the time that a domain controller waits before it notifies its first replication partner that there has been a change. The subsequent replication delay is the time that the domain controller waits after it has notified its first replication partner before it will notify its next partner. You may need to customize these settings so that replication happens as quickly as you need it to for data in the application partition. 17.7.2 Solution 17.7.2.1 Using a graphical user interface 1. Open ADSI Edit. 2. Connect to the configuration naming context of the forest the application partition is in if it is not already present in the left pane. 3. Expand the configuration naming context and click on the Partitions container. 4. In the right pane, right-click on the crossRef object that represents the application partition and select Properties. 538 5. Set the msDS-Replication-Notify-First-DSA-Delay and msDS-Replication- Notify-Subsequent-DSA-Delay attributes to the number of seconds you want for each delay (see the Discussion section for more details). 6. Click OK. 17.7.2.2 Using a command-line interface The Windows Server 2003 version of repadmin supports setting the notification delays: > repadmin /notifyopt <AppPartitionDN> /first:<FirstDelayInSeconds> /subs:[RETURN] <NextDelayInSeconds> For Windows 2000, you can create an LDIF file with the following contents: dn: <AppPartitionCrossRefDN> changetype: modify replace: msDS-Replication-Notify-First-DSA-Delay msDS-Replication-Notify-First-DSA-Delay: <FirstDelayInSeconds> - replace: msDS-Replication-Notify-Subsequent-DSA-Delay msDS-Replication-Notify-Subsequent-DSA-Delay: <NextDelayInSeconds> - If the file were named change_replication_delays.ldf, you'd run the following command: > ldifde -v -i -f change_replication_delays.ldf 17.7.2.3 Using VBScript ' This code sets the replication delay for an application partition ' SCRIPT CONFIGURATION strAppPartDN = "<AppPartitionDN>" ' e.g. dc=apps,dc=rallencorp,dc=com intFirstDelay = <FirstDelayInSeconds> intNextDelay = <NextDelayInSeconds> ' END CONFIGURATION set objRootDSE = GetObject("LDAP://RootDSE") strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)(nCName=" & strAppPartDN & "));" strAttrs = "cn,distinguishedName;" strScope = "onelevel" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for " & strAppPartDN else objRS.MoveLast set objAppPart = GetObject("LDAP://" & _ objRS.Fields("distinguishedName").Value ) 539 objAppPart.Put "msDS-Replication-Notify-First-DSA-Delay", intFirstDelay objAppPart.Put "msDS-Replication-Notify-Subsequent-DSA-Delay", intNextDelay objAppPart.SetInfo Wscript.Echo "Modified " & objRS.Fields("distinguishedName").Value end if 17.7.3 Discussion The settings that control the notification delay are stored in the msDS-Replication-Notify- First-DSA-Delay and msDS-Replication-Notify-Subsequent-DSA-Delay attributes on the application partition's crossRef object in the Partitions container. The time values are stored as seconds. The default for application partitions is 60 seconds for the first delay and 60 seconds for the subsequent delay. Recipe 17.8 Setting the Reference Domain for an Application Partition 17.8.1 Problem Whenever you create an object in Active Directory, the default security descriptor defined in the schema for the object's class is applied to the object. This default security descriptor may reference specific groups, such as Domain Admins, but it is not specific to a domain. This makes a lot of sense for domain-naming contexts, where the Domain Admins group in question would be the one defined in the domain. For application partitions, which don't contain a Domain Admins group, it is not so straightforward. Which domain's Domain Admins group do you use? To work around this issue, you can set a default security descriptor reference domain for an application partition by setting the msDS-SDReferenceDomain attribute of the partition's crossRef object. 17.8.2 Solution 17.8.2.1 Using a graphical user interface 1. Open ADSI Edit. 2. Connect to the Configuration naming context of the forest the application partition is in if it is not already present in the left pane. 3. Expand the Configuration naming context and click on the Partitions container. 4. In the right pane, right-click on the crossRef object that represents the application partition and select Properties. 5. Under Attributes, select the msDS-SDReferenceDomain attribute. 17.8.2.2 Using a command-line interface > ntdsutil "dom man" conn "co to se <DomainControllerName>" q "set nc ref domain[RETURN] <AppPartitionDN> <DomainDN>" q q 17.8.2.3 Using VBScript 540 ' This code sets the SD reference domain for the specified app partition ' SCRIPT CONFIGURATION ' DN of reference domain strRefDomainDN = "<DomainDN>" ' e.g. dc=emea,dc=rallencorp,dc=com ' Fully qualified DNS name of app partition strAppPart = "<AppPartitionFQDN>" ' e.g. app.rallencorp.com ' END CONFIGURATION set objRootDSE = GetObject("LDAP://RootDSE") strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)(dnsRoot=" & _ strAppPart & "));" strAttrs = "nCName,msDS-SDReferenceDomain,distinguishedName;" strScope = "onelevel" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for application partition " & _ strAppPart WScript.Quit else objRS.MoveLast WScript.Echo "Current Reference Domain: " & _ objRS.Fields("msDS-SDReferenceDomain").Value set objCrossRef = GetObject("LDAP://" & _ objRS.Fields("distinguishedName").Value ) objCrossRef.Put "msDS-SDReferenceDomain", strRefDomainDN objCrossRef.SetInfo WScript.Echo "New Reference Domain: " & _ objCrossRef.Get("msDS-SDReferenceDomain") end if 17.8.3 Discussion If you don't set the msDS-SDReferenceDomain attribute for an application partition, then a certain hierarchy is followed to determine the default security descriptor domain. These are the guidelines: • If the application partition is created as part of a new tree, the forest root domain is used as the default domain. • If the application partition is a child of a domain, the parent domain is the default domain. • If the application partition is a child of another application partition, the parent application partition's default domain is used. 17.8.4 See Also Recipe 10.19 for more on setting the default security descriptor for a class, Recipe 17.1 for creating an application partition, and MS KB 322669 (HOW TO: Manage the Application Directory Partition and Replicas in Windows Server 2003) . Application Directory Partition and Replicas in Windows Server 2003) Recipe 17.4 Finding the Replica Servers for an Application Partition 17.4.1 Problem You want to find the replica servers for an. automatically remove itself as a replica server for any application partitions it replicated. 17.3.4 See Also Recipe 17.4 for finding the replica servers for an application partition and MS KB. add any other domain controllers in the forest as replica servers assuming the domain controllers are running Windows Server 2003. The list of replica servers is stored in the msDS-NC-Replica- Locations