Today, I am to revise and re-post some older technical articles that I put together on another TechNet blog which I have since retired. In the interest of consolidating the posts so that they can be found at a single location, I am re-posting here, with updates/modifications as appropriate. I hope you enjoy them!
In the past, while working with a customer who was trying to understand why a Global Catalog query might be taking longer than expected, a question came up regarding the Partial Attribute Set (or PAS as it’s often called) and what it is exactly. Because not everyone understands this concept, I thought I'd write up a quick post about it.
To begin, 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 domain 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 in that domain automatically.
Having said that, the Active Directory forest for many large companies comprises more than one domain. And if you have a large enterprise with multiple domains, an added layer of complexity is introduced that administrators must be aware of. Because the amount of data within an AD DS domain can be quite extensive (hundreds of thousands, or even millions of objects), Active Directory is designed to replicate these objects only to Domain Controllers within the same domain. If another domain exists, the Domain Controllers for that other domain will not receive a copy of that information.
Partitions and Directory Replication
Before I proceed, let me clarify that last statement a bit. Active Directory (AD DS) is based on something called the multi-master model. This means that every Domain Controller within the replication scope of the objects it contains will all receive a copy of those objects. These objects will be identical (once replication completes) on every Domain Controller receiving a copy of the object. Because the potential exists for large directories to consume a great deal of network bandwidth (not to mention dramatically growing the size of the NTDS.DIT database on each Domain Controller), Active Directory limits replication of its directory.
To make replication more manageable, AD DS breaks its directory up into categories of data. Depending on which category the data belongs to, its replication scope will either be Domain or Forest-wide. The following table explains this:
Directory Partition | Definition | Replication Scope |
Domain | Contains objects such as users, computers, groups and contacts | Domain-wide |
Configuration | Contains configuration data used by the entire forest | Forest-wide |
Schema | The rules for the forest (which objects and attributes are allowed, which attributes are required for an object, etc.) | Forest-wide |
Application (optional) | Contains custom information specific to the application using it (DNS, for example) | Custom based on the needs of the application |
If you ever want to see these partitions directly to determine what each contains, the ADSI Edit tool is a good way to view this. From a Domain Controller or an admin workstation where the AD Tools are installed, open ADSI Edit as shown below:
From here, right-click the ADSI Edit icon in the left-hand pane and select ‘Connect to…’ option and the following window will open:
By choosing the drop-down list under ‘Select a well known Naming Context’, you can connect to the Domain, Configuration and Schema partitions residing on the DC you’ve chosen (though it’s hidden by the window in the picture, you can also use this window to select either the DC to which you are currently logged on or another DC in your forest)
NOTE: The Naming Context known as RootDSE is not a specific partition as such. Instead, it represents the root of the Directory Information Tree (the DIT) for a Domain Controller. It contains basic information about the directory server, its capabilities and configuration.
To see the information in one of these naming partitions, select it and it will be populated into ADSI Edit. From there, left-click the parent node and it will be possible to expand the partition to see and manipulate the data within it. In the screenshot below, I have selected the Default naming context (the Domain partition) for my local DC:
For those familiar with Active Directory Users and Computers (ADUC) or the newer Active Directory Administration Center (ADAC), this structure will look familiar. One essential difference, however, is that ADSI Edit represents all directory objects using their distinguishedName format (for example, OU=Lab versus just Lab in ADUC).
Note: We can also use ADSI Edit to connect to the application partitions as well, but that takes a few more steps than the ones listed above. For those interested, I will include those details in an upcoming blog so stay tuned.
Searching for Objects in Multiple Domains
As I’ve mentioned above, in order to reduce the size of the Active Directory database and limit bandwidth due to replication, the objects within the Domain partition (also known as the Domain Naming partition) 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. Configuration and Schema objects will be replicated into both of these domains because their replication scope of forest-wide, and depending on how the Application partition is defined it can also be replicated between forests. But for our present discussion, we care about information in the Domain partition.
What happens if a person in the EUROPE domain needs to look up a user residing in the USA domain? If she is an administrator, she has the choice of connecting to a Domain Controller in the USA domain, which could result in a slower response time (and this is not something average users will know how to do). But if she is not an admin and is using standard search tools (such as her contacts list in Outlook) and has only domain controllers in her local domain to query, all she will get is the users in her own domain.
The Solution: 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, just like any other Domain Controller in the domain. In addition, however, Global Catalogs also contain a read-only copy of the objects belonging to the Domain Naming partition from every other domain in the forest (there is no need to do this with the Forest and Configuration partitions as these are already replicated forest-wide, and each Application partition is replicated based on what you specify). 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 (applications such as Outlook do this by default so there is no need to take special steps in most cases).
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 she finds that the attribute she's interested in is not there? If she looks up this attribute for users in EUROPE she can find it, but she can't see it if she's querying the user in the USA domain. This is where the Partial Attribute Set (PAS) comes in.
Remember how I said that the Domain Naming partition is only replicated within the domain to preserve space and bandwidth? As it turns out, the PAS is also used to help preserve space on the Global Catalogs in the forest. To do this, AD DS designates only certain attributes to replicate to each Global Catalog. To clarify, every Global Catalog contains a full writeable copy of the Domain Naming partition from its own domain. This includes every attribute of every object in the Domain Naming partition. But when it comes to the objects in the Domain Naming partition from other domains, only certain attributes (those belonging to the Partial Attribute Set) are replicated between domains. This list includes the majority of attributes that your users will ever want, but it won't include things like certain system attributes, custom attributes defined by your business, etc.
To give an example of the difference when querying an object residing on the local domain controller versus the read-only copy of the same object as seen from a Global Catalog in another domain, consider the following list of attributes:
ATTRIBUTES FROM A STANDARD LDAP QUERY
dn: CN=scott,OU=Users,OU=Lab,DC=cert,DC=local
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: scott
givenName: scott
distinguishedName: CN=scott,OU=Users,OU=Lab,DC=cert,DC=local
instanceType: 4
whenCreated: 20150226135445.0Z
whenChanged: 20150226140527.0Z
displayName: scott
uSNCreated: 12733
memberOf: CN=Domain Admins,CN=Users,DC=cert,DC=local
memberOf: CN=Enterprise Admins,CN=Users,DC=cert,DC=local
memberOf: CN=Schema Admins,CN=Users,DC=cert,DC=local
uSNChanged: 12837
name: scott
objectGUID:: UDm/YKSQU0qG8Uvq6Is8xA==
userAccountControl: 66048
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 0
lastLogoff: 0
lastLogon: 130695726274467027
pwdLastSet: 130694324858513594
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAoDvDG0e5tebi0eW1UAQAAA==
adminCount: 1
accountExpires: 9223372036854775807
logonCount: 12
sAMAccountName: scott
sAMAccountType: 805306368
userPrincipalName: scott@cert.local
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=cert,DC=local
dSCorePropagationData: 20150226140527.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 130694326252478417
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=scott,OU=Users,OU=Lab,DC=cert,DC=local
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: scott
givenName: scott
distinguishedName: CN=scott,OU=Users,OU=Lab,DC=cert,DC=local
instanceType: 4
whenCreated: 20150226135445.0Z
whenChanged: 20150226140527.0Z
displayName: scott
uSNCreated: 12733
memberOf: CN=Domain Admins,CN=Users,DC=cert,DC=local
memberOf: CN=Enterprise Admins,CN=Users,DC=cert,DC=local
memberOf: CN=Schema Admins,CN=Users,DC=cert,DC=local
uSNChanged: 12837
name: scott
objectGUID:: UDm/YKSQU0qG8Uvq6Is8xA==
userAccountControl: 66048
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAoDvDG0e5tebi0eW1UAQAAA==
sAMAccountName: scott
sAMAccountType: 805306368
userPrincipalName: scott@cert.local
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=cert,DC=local
dSCorePropagationData: 20150226140527.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 130694326252478417
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, all that’s needed is to run the LDIFDE command line tool that is present on every Domain Controller and can be added to administrator workstations.
For the standard LDAP Query (the one connecting to the writeable Domain Naming partition in my local domain), I used the following LDIFDE command:
ldifde -f c:\scripts\output-389.txt -d "CN=scott,OU=Users,OU=Lab,DC=cert,DC=local" –t 389
When doing a Global Catalog query, my LDIFDE command line looked like the following:
ldifde -f c:\scripts\output-3268.txt -d "CN=scott,OU=Users,OU=Lab,DC=cert,DC=local" –t 3268
To understand the parameters I used, consider the following:
- -f is the parameter which allows me to specify the filepath where I will store the output of the query. The name I chose is entirely up to me. In each case, I specified which port I was connecting to so that review of the results would be easier to interpret.
- -d is the distinguished name I queried (known as the RootDN in the help files). If I had instead chosen to query a higher-level portion of the directory tree (such as OU=Lab,DC=cert,DC=local) I would have gotten the information for that object plus every object beneath it. In my case, I only wanted a single object (CN=scott) so I queried that object specifically. Since there are no child objects beneath CN=scott, only one object is returned.
- -t is where I specify the port I am querying. In the first query, I specify the standard LDAP port (389) and in the second query I specify the GC port (3268). This allows me to see the full set of populated attributes versus the list of attributes replicated to the read-only copy of the Domain Naming partition contained by the Global Catalog
NOTE: In my test, I used a single Domain Controller for both queries. My lab has only a single domain and I was still able to see the differences between querying the writeable copy of the Domain Naming partition and the read-only copy present in the Global Catalog.
Extending the Partial Attribute Set
So now we understand the difference between the Domain Naming partition and the read-only copy sent to all Global Catalogs. But what if we need to include some additional attributes in the Partial Attribute Set? For example, what if there is an essential attribute needed by our employees in every domain of our forest? How do we get that attribute to replicate to the Global Catalog? In this case, if we need additional attributes to be replicated as part of the PAS, we can make this change fairly easily in the Active Directory Schema (NOTE: Do not make any changes in the 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. To do this, we will need to use an account that is a member of the Schema Administrators group.
- Connect to the Domain Controller that houses the Schema Master role for the forest (all Schema changes must be made on the DC housing the Schema Master FSMO role)
- Before doing anything else, make sure that the Active Directory Schema snap-in is available.
- Open a blank MMC window by typing mmc.exe from the Run window.
- Within the MMC that opens, select File and then Add/Remove Snap-in.
- From the resulting list, look for Active Directory Schema as shown below:
- If the snap-in is not present (as is the case in the screenshot above), type the following in a an elevated command prompt:
regsvr32 schmmgmt.dll
- If successful, the following window will be displayed:
- Once this has been run, check again under Add/Remove Snap-in and Active Directory Schema will now be available:
- From within the Active Directory Schema snap-in, navigate to the Attributes folder and scroll down on the right to find the desired attribute. In our example, perhaps the ‘drink’ attribute is considered essential (it’s a bit unusual, I admit, but never overestimate what may be considered essential to a company)
- Right-click the attribute and select Properties.
- In the resulting window, select the check box that says Replicate this attribute to the Global Catalog and select OK to close the window.
Selecting this checkbox adds the attribute to the Partial Attribute Set so that it is now included when an object is replicated to the Global Catalog
- Repeat this process with any additional attributes that need to be added to the Partial Attribute Set
Once these changes have been made, we will need to allow time for replication to complete (remember that the Schema must replicate to every Domain Controller in the forest and depending on the scope of the forest, the replication topology, etc. this may take some time). Once replication is completed, we will want to use LDIFDE to query again as we did above to verify that the new attribute is now part of the Partial Attribute Set.
Summary
In this article, I have outlined how Global Catalogs provide read-only access to the Domain Naming partition for every domain in an Active Directory (AD DS) forest. I have shown how to identify the differences between querying the Domain Naming partition with LDAP and the read-only partition of the GC via port 3268. I have also shown how it’s possible to add (or remove) attributes from the Partial Attribute Set. Typically, these changes are not needed, but if there is a compelling business reason to make such a change, the functionality is available.
Always remember when making Schema changes, it is essential to use precautions and test thoroughly in a non-production environment before implementing in production.