Export (0) Print
Expand All

Active Directory Replication and Indexing

Microsoft® Windows® 2000 Scripting Guide

Active Directory is well suited for handling a large number of read and search operations, and a significantly smaller number of changes and updates. The data in Active Directory is replicated, meaning that updates occurring to the Active Directory on one domain controller are sent to other domain controllers in the network. Because the data is replicated, Active Directory is not well suited for dynamic data that frequently changes - for example, CPU utilization and Internet stock prices.

Note

  • However, you can retrieve frequently changing data, such as computer system performance and event logging information, by using WMI. For more information about WMI, see "WMI Scripting Primer" in this book.

A critical part of managing Active Directory with ADSI scripts is knowing where directory objects are replicated. Active Directory is divided into partitions to reduce replication. Partitions are either fully replicated (full replicas) or partially replicated (partial replicas). Full replicas are partitions that are replicated to every domain controller in the forest and can be read or written to from any domain controller. Partial replicas are read-only partitions that contain a subset of data contained in Active Directory.

Partitions Replicated on Domain Controllers

The three full replicas found on each domain controller are the:

  • Schema partition. This partition contains all of the classes and attributes defined in the forest.

  • Configuration partition. This partition contains system information that all domain controllers must store - this includes information about the various partitions, forest-wide services, sites, and well-known security principals in the forest.

  • Domain Directory partition. This partition contains all of the objects created in a particular domain and is replicated to every domain controller within a domain. Unlike the other two types of partitions, which are full replicas, this partition is different for each domain.

Note

  • Other replicas might be present on domain controllers.

Attributes Replicated to the Global Catalog

All domain controllers designated as Global Catalog servers contain a partial replica of all other domain directory partitions in the forest. This partial replica, appropriately named the Global Catalog, contains all of the objects in the domain directory partition, but only a subset of the attributes of these objects. Knowing which attributes are contained in the Global Catalog is critical to creating scripts that perform search operations efficiently. For example, if you write a script to request an attribute that is not in the Global Catalog and you want the script to return results from more than one domain, you must use referral chasing. Referral chasing increases network congestion and can cause the script to respond slowly. For information about referral chasing, see "Searching Active Directory" earlier in this chapter.

To avoid referral chasing, read attributes that are contained in the Global Catalog. By doing so, you ensure that the script contacts a single domain controller designated as a Global Catalog server to fulfill the request of the script.

The isMemberOfPartialAttributeSet attribute contains a True or False value indicating whether an attribute is replicated to the Global Catalog. Listing 5.50 shows how to determine whether an attribute is replicated to the Global Catalog.

  1. Initialize a variable named strAttributeName with the common name of an attribute.

    In this example, the script tests the given-name attribute. To test other attributes, simply initialize the attribute with the common name of a different attribute.

  2. Use rootDSE to determine the value of the schemaNamingContext attribute.

  3. Bind to the attribute in the schema container using the GetObject function and the LDAP provider.

  4. Initialize the blnInGC variable with the Boolean value contained in the isMemberOfPartialAttributeSet attribute.

    • If blnInGC is True, echo to the command window that the attribute is replicated to the Global Catalog.

    • Otherwise, echo to the command window that the attribute is not replicated to the Global Catalog.

Listing 5.50 Reading the isMemberOfPartialAttributeSet Attribute of an Attribute

  
1
2
3
4
5
6
7
8
9
10
11
12
13
14


strAttributeName = "cn=given-name"

Set objRootDSE = GetObject("LDAP://rootDSE")
Set objSchemaAttribute = GetObject("LDAP://" & strAttributeName & "," & _
 objRootDSE.Get("schemaNamingContext"))

blnInGC = objSchemaAttribute.Get("isMemberOfPartialAttributeSet")
If blnInGC Then
 Wscript.Echo strAttributeName & _
 " is replicated to the Global Catalog."
 Else
 Wscript.Echo "The " & strAttributeName & _
 " is not replicated to the Global Catalog."
End If

When this script runs, it echoes a message indicating that the attribute is contained in the Global Catalog, as shown:



cn=given-name is replicated to the Global Catalog.

After you have determined that an attribute is in the Global Catalog, you specify GC instead of LDAP when constructing a query string. For information about creating a query string that uses the Global Catalog, see "Searching Active Directory" earlier in this chapter.

In Listing 5.50, you might have noticed that the script searches for an attribute (isMemberOfPartialAttributeSet) in an attribute (givenName or cn=given-name). This illustrates the fact that attributes can contain attributes. In fact, if you view the schema from a tool such as the ADSI Edit snap-in, you will see that attributes and classes are viewed as objects. As you know, Active Directory objects contain attributes.

Indexed Attributes

Another important aspect to consider when performing a search operation is whether the attribute to be sorted is indexed. Indexed attributes are already sorted, which reduces the processing requirements placed on a domain controller when you perform a search operation that includes sorting the result set. For information about enabling a sort operation in a search, see "Searching Active Directory" earlier in this chapter.

The searchFlags attribute contains an integer value indicating, among other things, whether an attribute is indexed. Listing 5.51 shows how to determine whether an attribute is indexed. This script is similar to Listing 5.50, so only steps that differ are shown here.

  1. Set the IS_INDEXED constant to determine later in the script whether an attribute is indexed.

  2. Use rootDSE to determine the value of the schemaNamingContext attribute.

  3. Initialize the intSearchFlags variable with the integer value contained in the searchFlags attribute (line 8).

  4. Use rootDSE to determine the value of the schemaNamingContext attribute.

  5. Use the AND operator to evaluate the value of IS_INDEXED against the first bit in the searchFlags attribute.

    • If the first bit in the searchFlags attribute is on, echo to the command window that the attribute is indexed.

    • Otherwise, echo to the command window that the attribute is not indexed.

Listing 5.51 Reading the searchFlags Attribute to Determine Whether an Attribute Is Indexed

  
1
2
3
4
5
6
7
8
9
10
11
12
13


Const IS_INDEXED = 1
strAttributeName = "cn=given-name"

Set objRootDSE = GetObject("LDAP://rootDSE")
Set objSchemaAttribute = GetObject("LDAP://" & strAttributeName & "," & _
 objRootDSE.Get("schemaNamingContext"))

intSearchFlags = objSchemaAttribute.Get("searchFlags")
If IS_INDEXED AND intSearchFlags Then
 Wscript.Echo strAttributeName & " is indexed."
Else
 Wscript.Echo strAttributeName & " not indexed."
End If

When this script runs, it echoes a message indicating that the given-name attribute is indexed, as shown:



cn=given-name is indexed.

Attributes That Are Both Replicated to the Global Catalog and Indexed

Ideally, search operations should use attributes that are both replicated to the global catalog and indexed. To retrieve a result set containing all attributes that meet both of these criteria by default, it is more efficient to perform a search operation than it is to bind to each attribute individually. For more information about performing efficient search operations, see "Optimizing Search Performance" earlier in this chapter.

Caution

  • You can configure attributes in the schema to be replicated to the Global Catalog or to be indexed by using a tool such as the Active Directory Schema snap-in. However, you must be cautious about how you modify the schema because improper modifications can damage Active Directory or severely affect network and server performance.

Listing 5.52 shows how to perform a search operation to retrieve a result set of all attributes that are both replicated to the Global Catalog and indexed. The steps to complete this task are similar to the search tasks shown earlier in this chapter; therefore, steps are summarized.

  1. Set the IS_INDEXED constant to determine later in the script whether an attribute is indexed.

  2. Use rootDSE to determine the value of the schemaNamingContext attribute and initialize the strADsPath variable.

  3. Using ADO, query Active Directory for all AttributeSchema objects and return the lDAPDisplayName, isMemberOfPartialAttributeSet, and searchFlags attributes of the objects.

    The objectCategory=AttributeSchema returns objects in the schema that are defined as attributes.

  4. Use a While Wend statement to read each record in the result set.

  5. For each record in the result set, determine both whether the attribute is contained in the Global Catalog - isMemberOfPartialAttributeSet = True - and whether the attribute is indexed - first bit of the searchFlags attribute is on (lines 20 and 21).

    If both conditions are true, display the lDAPDisplayName of the attribute (stored in the strAttribute variable).

Listing 5.52 Locating Attributes That Are in the Global Catalog and Indexed

  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


Const IS_INDEXED = 1

Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider=ADsDSOObject;"

Set objCommand = CreateObject("ADODB.Command")
objCommand.ActiveConnection = objConnection

Set objRootDSE = GetObject("LDAP://rootDSE")
strADsPath = "<LDAP://" & objRootDSE.Get("schemaNamingContext") & ">"
objCommand.CommandText = strADsPath & _
 ";(objectCategory=AttributeSchema);" & _
 "lDAPDisplayName,isMemberOfPartialAttributeSet,searchFlags;onelevel"

Set objRecordSet = objCommand.Execute
Wscript.Echo "Attributes in Global Catalog and indexed: "
While NOT objRecordSet.EOF
 strAttribute = objRecordSet.Fields("lDAPDisplayName")
 If objRecordSet.Fields("isMemberOfPartialAttributeSet") AND _
 (IS_INDEXED AND objRecordSet.Fields("searchFlags")) Then
 Wscript.Echo strAttribute
 End If
 objRecordSet.MoveNext
Wend

objConnection.Close

When this script runs, it echoes the lDAPDisplayName of the attributes that are both contained in the Global Catalog and indexed, as shown in the following abbreviated result set:



Attributes in Global Catalog and indexed:
AltSecurityIdentities
cn
displayName
mail
...
name
sAMAccountName
sAMAccountType
servicePrincipalName
sIDHistory
sn

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2015 Microsoft