Global Catalogs and the Partial Attribute Set

Recently, while working with a customer who was trying to understand why a Global Catalog query might be taking longer than expected, the question of the Partial Attribute Set came up.  Because not everyone understood this concept, I thought I'd write up a quick post about it.

First, Active Directory is designed so that the objects you need (users, groups, computers, printers, etc) don't just sit on one computer.  Instead, they are replicated throughout the Active Directory environment so that users in California can access a Domain Controller in Los Angeles and see the same objects as the user logging into a Domain Controller in New York.  If you have only a single Active Directory domain, these objects will be replicated to every Domain Controller.

But if you have a large enterprise with multiple domains, an added layer of complexity is introduced.  In order to reduce the size of the Active Directory database and limit bandwidth due to replication, these objects are only replicated within their own domain.  So if you have two domains, USA and EUROPE, the users in the USA domain won't appear in the EUROPE domain and vice versa (NOTE: certain other types of objects such as configuration and schema objects are replicated throughout the entire Active Directory forest).  But what happens if a person in the EUROPE domain needs to look up a user residing in the USA domain?  He has the choice of talking to a Domain Controller in the USA domain, which could result in a slower response time, or he could query his domains Global Catalogs.

The Global Catalog in Active Directory Domain Services (AD DS) a specialized type of Domain Controller that contains the full copy of the objects from its own domain, but which also contains a read-only copy of the objects from every other domain in the forest.  Given this, the user in EUROPE could simply query the Global Catalog (using port 3268 versus the standard LDAP port 389) in order to see the user object from the USA domain.

So far so good.  This is a well-understood concept by most Active Directory administrators.  But what if this user in EUROPE wants to look up a particular attribute about the user in USA and he finds that the attribute he's interested in is not there?  If he looks up this attribute for users in EUROPE he can find it, but he can't see it if he's querying the user in the USA domain.  This is where the Partial Attribute Set (PAS) comes in.

Because of a desire to preserve bandwidth and the size of the Active Directory database (known as NTDS.DIT) on each Global Catalog, only certain attributes have been selected by default to replicate to each Global Catalog.  This list includes the majority of attributes that your users will ever want, but it won't include things like custom attributes defined by your business.

To give an example of the differences when querying an object against the local domain controller versus the read-only copy of a remote domain located in the Global Catalog, consider the following list of attributes:

ATTRIBUTES FROM A STANDARD LDAP QUERY

dn: CN=Administrator,CN=Users,DC=W2K8Forest,DC=com
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Administrator
description: Built-in account for administering the computer/domain
distinguishedName: CN=Administrator,CN=Users,DC=W2K8Forest,DC=com
instanceType: 4
whenCreated: 20120120203458.0Z
whenChanged: 20120201204941.0Z
uSNCreated: 8196
memberOf: CN=Group Policy Creator Owners,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Domain Admins,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Enterprise Admins,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Schema Admins,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Administrators,CN=Builtin,DC=W2K8Forest,DC=com
uSNChanged: 16395
name: Administrator
objectGUID:: ucm0/DkRr0CdQJRpDFSvUQ==
userAccountControl: 512
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 129733677405425192
lastLogoff: 0
lastLogon: 129733677458577130
logonHours:: ////////////////////////////
pwdLastSet: 129714846924858750
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAxrZqoX7ixyzK8IdU9AEAAA==
adminCount: 1
accountExpires: 0
logonCount: 14
sAMAccountName: Administrator
sAMAccountType: 805306368
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=W2K8Forest,DC=com
isCriticalSystemObject: TRUE
dSCorePropagationData: 20120120205349.0Z
dSCorePropagationData: 20120120205349.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 129726029816125962

Now, compare this to the list of attributes when querying the same object on a Global Catalog.

ATTRIBUTES FROM A GLOBAL CATALOG QUERY

dn: CN=Administrator,CN=Users,DC=W2K8Forest,DC=com
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Administrator
description: Built-in account for administering the computer/domain
distinguishedName: CN=Administrator,CN=Users,DC=W2K8Forest,DC=com
instanceType: 4
whenCreated: 20120120203458.0Z
whenChanged: 20120201204941.0Z
uSNCreated: 8196
memberOf: CN=Group Policy Creator Owners,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Domain Admins,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Enterprise Admins,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Schema Admins,CN=Users,DC=W2K8Forest,DC=com
memberOf: CN=Administrators,CN=Builtin,DC=W2K8Forest,DC=com
uSNChanged: 16395
name: Administrator
objectGUID:: ucm0/DkRr0CdQJRpDFSvUQ==
userAccountControl: 512
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAxrZqoX7ixyzK8IdU9AEAAA==
sAMAccountName: Administrator
sAMAccountType: 805306368
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=W2K8Forest,DC=com
dSCorePropagationData: 20120120205349.0Z
dSCorePropagationData: 20120120205349.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 129726029816125962

The difference in these lists is that only the attributes belonging to the Partial Attribute Set for user objects is populated in the Global Catalog's copy of the Administrator account.  And if you want to try this test yourself, you can read the following article about using LDIFDE:

LDIFDE

So now you understand the difference.  But what if you need to include some additional attributes in your Partial Attribute Set? If you need additional attributes to be replicated as part of the PAS, the good news is that you can make this change in the Active Directory Schema (NOTE: Do not make any changes in your AD Schema without thoroughly testing it in a non-production environment). 

Below is a step-by-step description of how to tell whether an attribute is part of the Partial Attribute Set and how to change it if needed.  Remember, you will want to use an account that is a member of the Schema Administrators group

  1. Go to the Domain Controller that houses your Schema Master role for your forest as you will want to make your changes there.
  2. Before you do anything else, you'll need to make sure that the Active Directory Schema snap-in is available for you to work with.  You do this in the following way:
    1. Open a blank MMC window by typing mmc.exe from Start/Run.

    2. Within the MMC that opens, select File and then Add/Remove Snap-in.

    3. From the resulting list, look for Active Directory Schema.

    4. If the snap-in is not present, type the following in a command prompt (make sure that you are using elevated privileges when opening the command prompt or you will get an error):

       regsvr32 schmmgmt.dll
      
    5. Once you've run this, check again under Add/Remove Snap-in and you should see Active Directory Schema.

  3. From within the Active Directory Schema snap-in, navigate to the Attributes folder and scroll down on the right until you see the attribute you want to add to the Partial Attribute Set.
  4. Right-click the attribute and select Properties.
  5. In the resulting window, select the check box that says Replicate this attribute to the Global Catalog and select OK to close the window.
  6. Repeat this process with any additional attributes you need to add to the Partial Attribute Set
  7. Close the snap-in, saving it if you choose to do so.

Once you've made this change, allow time for replication to complete between domains and then use LDIFDE to query again.