For example, a search for anr=Jim Smith would translate into the following query: • An OR filter with every attribute in the ANR set against Jim Smith* • A filter for givenName = Jim*
Trang 1objAttr.SetInfo
WScript.Echo "New ANR attribute: " & strAttrName
The CLI and VBScript solutions assume that searchFlags wasn't previously set and just blindly overwrites whatever value is present if one was Check out Recipe 4.12 for a better solution that will enable the bit you want without overwriting any previous settings
10.13.3 Discussion
ANR is an efficient search algorithm that allows for a complex search filter to be written using a single comparison For example, a search for (anr=Jim Smith) would translate into the
following query:
• An OR filter with every attribute in the ANR set against Jim Smith*
• A filter for givenName = Jim* and sn = Smith*
• A filter for givenName = Smith* and sn = Jim*
These filters are ORed together and then processed by Active Directory Since all default ANR attributes are also indexed, the query return should come back quickly
Here is a list of the default attributes that are included as part of ANR searches The LDAP display name of the attribute is shown first with the common name in parenthesis
• displayName (Display-Name)
• givenName (Given-Name)
• legacyExchangeDN (Legacy-Exchange-DN)
• msDS-AdditionalSamAccountName (ms-DS-Additional-Sam-Account-Name)
• physicalDeliveryOfficeName (Physical-Delivery-Office-Name)
• name (RDN)
• sAMAccountName (SAM-Account-Name)
• sn (Surname)
msDS-AdditionalSamAccountName was added as an ANR attribute in Windows Server 2003
It is important to make sure that any new ANR attributes are also indexed ANR searches are intended to be very fast, and if a non-indexed attribute was added to the set, it could dramatically impact the performance of the searches
You can find which attributes are included in the ANR set by using the following search criteria:
Base
cn=Schema,cn=Configuration,<ForestRootDN>
Filter
Trang 2Scope
onelevel
Alternatively, to find attributes that aren't included in ANR, change the previous search filter to the following:
(&(objectcategory=attributeSchema)(!(searchFlags:1.2.840.113556.1.4.803:=4)))
10.13.4 See Also
Recipe 4.12 for modifying a bit-flag attribute, Recipe 10.7 for adding a new attribute, MS KB
243299 (Ambiguous Name Resolution for LDAP in Windows 2000), and MS KB 243311 (Setting an Attribute's searchFlags Property to Be Indexed for ANR)
Recipe 10.14 Adding or Removing an Attribute in the Global Catalog
10.14.1 Problem
You want to add or remove an attribute in the global catalog
10.14.2 Solution
For Windows 2000 Active Directory, you need to enable schema modifications before proceeding See Recipe 10.2 for more information
10.14.2.1 Using a graphical user interface
1 Open the Active Directory Schema snap-in
2 In the left pane, click on the Attributes folder
3 In the right pane, double-click the attribute you want to edit
4 Check the box beside Replicate this attribute to the Global Catalog to add to the global catalog, or uncheck to remove the global catalog
5 Click OK
10.14.2.2 Using a command-line interface
You can add an attribute to the global catalog by using the ldifde utility and an LDIF file that contains the following:
dn: cn=<AttrCommonName>,cn=schema,cn=configuration,<ForestRootDN>
changetype: modify
replace: isMemberOfPartialAttributeSet
Trang 3-
If the LDIF file were named add_gc_attr.ldf, you would run the following command:
> ldifde -v -i -f add_gc_attr.ldf
10.14.2.3 Using VBScript
' This code adds an attribute to the global catalog
' - SCRIPT CONFIGURATION -
' Set to the common name (not LDAP display dame) of the attribute
strAttrName = "<AttrCommonName>" ' e.g surname
' Set to TRUE to add to GC, set to FALSE to remove from GC
boolAddtoGC = TRUE
' - END CONFIGURATION -
set objRootDSE = GetObject("LDAP://RootDSE")
set objAttr = GetObject("LDAP://cn=" & strAttrName & "," & _
objRootDSE.Get("schemaNamingContext"))
objAttr.Put "isMemberOfPartialAttributeSet", boolAddtoGC
objAttr.SetInfo
WScript.Echo "Added attribute to GC: " & strAttrName
10.14.3 Discussion
Each domain controller in a forest replicates a copy of the Domain naming context for its own domain as well as copies of the forest-wide Configuration and Schema partitions However, domain controllers do not replicate Domain naming contexts for other domains in the forest When enabled as a global catalog server, a domain controller will replicate partial, read-only replicas of all the objects in other domains in the forest
Searching against the global catalog is useful when you need to perform a single search across several naming contexts at once The global catalog stores only a subset of each object's
attributes, which is why it is considered a partial replica Attributes stored in the global catalog are considered part of the partial attribute list (PAS) The attributes that are part of the PAS should be either ones you'd want to use as part of searches against the global catalog, or ones you would want returned after searching the global catalog
You can add attributes that are stored in the global catalog by setting the
isMemberOfPartitalAttributeSet attribute of an attributeSchema object to TRUE
Likewise, to remove an attribute from the partial attribute set, you need to set
isMemberOfPartitalAttributeSet to FALSE for the target attribute
With Windows 2000, anytime you added an attribute to the partial attribute set, a full sync of all of the global catalog contents was done for every global catalog server This could have a major impact on replication in some multidomain environments, as the amount of data that needs to replicate across your forest could be significant Fortunately, this limitation was removed in Windows Server 2003 so that a full sync is no longer
Trang 4force a global catalog sync, even under Windows 2000
You can find which attributes are included in the global catalog by using a query with the
following criteria:
Base
cn=Schema,cn=Configuration,<ForestRootDN>
Filter
(&(objectcategory=attributeSchema)(isMemberOfPartitalAttributeSet=TRUE))
Scope
onelevel
Alternatively, to find attributes that aren't in the global catalog, you only need to change part of the previous filter to the following:
(isMemberOfPartialAttributeSet=FALSE)
10.14.4 See Also
MS KB 229662 (How to Control What Data Is Stored in the Global Catalog), MS KB 230663 (HOW TO: Enumerate Attributes Replicated to the Global Catalog), MS KB 232517 (Global Catalog Attributes and Replication Properties), MS KB 248717 (How to Modify Attributes That Replicate to the Global Catalog), MS KB 257203 (Common Default Attributes Set for Active Directory and Global Catalog), and MS KB 313992 (HOW TO: Add an Attribute to the Global Catalog in Windows 2000)
Recipe 10.15 Finding the Nonreplicated and
Constructed Attributes
10.15.1 Problem
You want to find the attributes are not replicated or are constructed by Active Directory
10.15.2 Solution
10.15.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 domain controller (or leave blank to do a serverless bind)
4 For Port, enter 389
5 Click OK
6 From the menu, select Connection Bind
7 Enter credentials of a domain user
Trang 58 Click OK
9 From the menu, select Browse Search
10 For BaseDN, type the Schema Container DN (e.g.,
cn=schema,cn=configuration,dc=rallencorp,dc=com)
11 For Scope, select One Level
12 To find nonreplicated attributes, use the following for Filter:
(&(objectcategory=attributeSchema)(systemFlags:1.2.840.113556.1.4.803:= 1))
13 To find constructed attributes, use the following for Filter:
(&(objectcategory=attributeSchema)(systemFlags:1.2.840.113556.1.4.803:= 4))
14 Click Run
10.15.2.2 Using a command-line interface
To find the nonreplicated attributes, use the following command:
> dsquery * cn=schema,cn=configuration,<ForestRootDN> -scope onelevel -attr
"cn"[RETURN]
-filter
"(&(objectcategory=attributeSchema)(systemFlags:1.2.840.113556.1.4.803:=1))"
To find the constructed attributes, use the following command:
> dsquery * cn=schema,cn=configuration,<ForestRootDN> -scope onelevel -attr
"cn"[RETURN]
-filter
"(&(objectcategory=attributeSchema)(systemFlags:1.2.840.113556.1.4.803:=4))"
10.15.2.3 Using VBScript
' This script will print out the nonreplicated and constructed attributes
set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("SchemaNamingContext") & ">;"
strFilter = "(&(objectcategory=attributeSchema)" _
& "(systemFlags:1.2.840.113556.1.4.803:=1));"
strAttrs = "cn;"
strScope = "onelevel"
set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
objRS.MoveFirst
WScript.Echo "Nonreplicated attributes: "
while Not objRS.EOF
Wscript.Echo " " & objRS.Fields(0).Value
objRS.MoveNext
Trang 6strFilter = "(&(objectcategory=attributeSchema) " _
& "(systemFlags:1.2.840.113556.1.4.803:=4));"
set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
objRS.MoveFirst
WScript.Echo ""
WScript.Echo "Constructed attributes: "
while Not objRS.EOF
Wscript.Echo " " & objRS.Fields(0).Value
objRS.MoveNext
wend
10.15.3 Discussion
The systemFlags attribute of attributeSchema objects defines a few special attribute
properties, including whether an attribute is not replicated between domain controllers and whether it is dynamically constructed by Active Directory
Most attributes are replicated after they are updated on an object, but some never replicate
between domain controllers These attributes are considered nonreplicated An example of a nonreplicated attribute you may be familiar with is the lastLogon attribute that stores the last logon timestamp for user and computer objects Whenever a user or computer logs in to Active Directory, the authenticating domain controller updates the user or computer's lastLogin
attribute, but the update does not get replicated out to other domain controllers
Constructed attributes are automatically maintained by Active Directory and cannot be set
manually A good example of a constructed attribute is the new
msDS-Approx-Immed-Subordinates that is available in Windows Server 2003 That attribute contains the approximate number of child objects within a container Obviously this attribute wouldn't be of much value if you had to maintain it, so Active Directory does it automatically
One of the downsides to constructed attributes is that you cannot search against them For
example, I cannot perform a search to find all containers that have more than 10 objects in them (i.e., msDS-Approx-Immed-Subordinates>10) This would return an operations error
Constructed attributes can only be returned as part of the attribute set for a query and not used as part of the query itself
To find the nonreplicated or constructed attributes you have to use a bitwise LDAP filter against
attributeSchema objects A bit value of 1 indicates the attribute is non-replicated and a value
of 4 indicates the attribute is constructed
10.15.4 See Also
Recipe 4.9 for searching with a bitwise filter
Trang 7Recipe 10.16 Finding the Linked Attributes
10.16.1 Problem
You want to find attributes that are linked
10.16.2 Solution
10.16.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 domain controller (or leave blank to do a serverless bind)
4 For Port, enter 389
5 Click OK
6 From the menu, select Connection Bind
7 Enter credentials of a domain user
8 Click OK
9 From the menu, select Browse Search
10 For BaseDN, type the Schema container DN (e.g.,
cn=schema,cn=configuration,dc=rallencorp,dc=com)
11 For Scope, select One Level
12 To find linked attributes, use the following for Filter:
(&(objectcategory=attributeSchema)(linkid=*))
13 Click Run
10.16.2.2 Using a command-line interface
> dsquery * cn=schema,cn=configuration,<ForestRootDN> scope onelevel
-filter[RETURN]
"(&(objectcategory=attributeSchema)(linkid=*))" -attr cn linkID
10.16.2.3 Using VBScript
' This code prints out all of the attributes that are linked
' and their corresponding linkID values
set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("SchemaNamingContext") & ">;"
strFilter = "(&(objectcategory=attributeSchema)(linkid=*));"
strAttrs = "cn,linkid;"
strScope = "onelevel"
set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
objRS.MoveFirst
while Not objRS.EOF
Wscript.Echo objRS.Fields(1).Value & " : " & objRS.Fields(0).Value
Trang 810.16.3 Discussion
The values of some attributes in Active Directory are linked For example, if you set the manager
attribute on one user object to be the DN of a second user object, the reports attribute on the second user object will automatically contain the first user object's DN In this example, the
manager attribute, or the attribute that gets set, is considered the forward link and the reports
attribute, or the attribute that automatically gets calculated, is called the back link Another common example is group membership The member attribute of the group object represents the forward link, while the memberOf attribute of the corresponding object (e.g., user) represents the back link
You can identify which attributes are linked in the schema by searching for attributeSchema
objects that have a linkID attribute that contains some value The linkID value for a forward-link attribute will be an even, positive number The corresponding back-forward-link attribute will be the
forward-linkID plus 1 For example, the manager attribute linkID is 42 and the back-link
reports attribute has a linkID of 43
Recipe 10.17 Finding the Structural, Auxiliary,
Abstract, and 88 Classes
10.17.1 Problem
You want to list the structural, auxiliary, abstract, and 88 classes
10.17.2 Solution
10.17.2.1 Using a graphical user interface
1 Open the Active Directory Schema snap-in
2 In the left pane, click on the Classes folder
3 In the right pane, the list of all the classes will be displayed The Type column contains the type of class Even though you can click on the column header, it currently does not sort the classes by type
10.17.2.2 Using a command-line interface
> dsquery * cn=schema,cn=configuration,<ForestRootDN> -limit 0 -scope
onelevel[RETURN]
-filter "(objectcategory=classSchema)" -attr lDAPDisplayName
objectclasscategory
10.17.2.3 Using VBScript
' This code prints out classes of a particular type
' - SCRIPT CONFIGURATION -
Trang 9' Set the following to TRUE or FALSE depending if you want to
' view or not view classes of the type defined by the variable
boolShowStructural = TRUE
boolShowAuxiliary = TRUE
boolShowAbstract = TRUE
boolShow88 = TRUE
' - END CONFIGURATION -
set objRootDSE = GetObject("LDAP://RootDSE")
set objSchemaCont = GetObject("LDAP://cn=schema," & _
objRootDSE.Get("configurationNamingContext")) objSchemaCont.Filter = Array("classSchema")
WScript.Echo "Loading classes, this will take a few seconds."
for each objClass in objSchemaCont
WScript.StdOut.Write(".")
if objClass.Get("objectClassCategory") = 0 then
str88 = str88 & vbTab & objClass.Get("lDAPDisplayName") & vbCrlf
elseif objClass.Get("objectClassCategory") = 1 then
strStruct = strStruct & vbTab & _
objClass.Get("lDAPDisplayName") & vbCrlf
elseif objClass.Get("objectClassCategory") = 2 then
strAbst = strAbst & vbTab & objClass.Get("lDAPDisplayName") & vbCrlf elseif objClass.Get("objectClassCategory") = 3 then
strAux = strAux & vbTab & objClass.Get("lDAPDisplayName") & vbCrlf else
WScript.Echo "Unknown class type: " & _
objClass.Get("lDAPDisplayName") & vbCrlf
end if
next
WScript.Echo vbCrlf
if boolShowStructural = TRUE then
WScript.Echo "Structural Classes: "
WScript.Echo strStruct
WScript.Echo
end if
if boolShowAbstract = TRUE then
WScript.Echo "Abstract Classes: "
WScript.Echo strAbst
WScript.Echo
end if
if boolShowAuxiliary = TRUE then
WScript.Echo "Auxiliary Classes: "
WScript.Echo strAux
WScript.Echo
end if
if boolShow88 = TRUE then
WScript.Echo "88 Classes: "
WScript.Echo str88
WScript.Echo
end if
Trang 10There are four supported class types in the Active Directory schema The class type is defined by the objectClassCategory attribute on classSchema objects Each class type is used for a different purpose relating to organizing and inheriting classes Table 10-6 describes each type
Table 10-6 Object class category values
88 0 Legacy class type defined by the original X.500 standards It should not be
used for new classes
Structural 1 Used for instantiating objects Can be comprised of abstract, auxiliary, and
other structural classes
Abstract 2
Used to define a high-level grouping of attributes that can be used as part of other abstract or structural class definitions Objects cannot be instantiated using an abstract class
Auxiliary 3 Used as a collection of attributes that can be applied to other abstract,
auxiliary, or structural classes
Recipe 10.18 Finding the Mandatory and Optional
Attributes of a Class
10.18.1 Problem
You want to view the mandatory and optional attributes of a class
10.18.2 Solution
10.18.2.1 Using a graphical user interface
1 Open the Active Directory Schema snap-in
2 In the left pane, click on the Classes folder
3 In the right pane, double-click the class you want to view
4 Click on the Attributes tab
10.18.2.2 Using a command-line interface
> dsquery * cn=<ClassCommonName>,cn=schema,cn=configuration,<ForestRootDN>
-l[RETURN]
-scope base -attr mayContain mustContain systemMayContain systemMustContain
10.18.2.3 Using VBScript
' This code displays the mandatory and optional attributes for a class