Contact

Subscribe via Email

Subscribe via RSS

Categories

Creative Commons Attribution 4.0 International License
© Rakhesh Sasidharan

Elsewhere

Replicate with repadmin

The following command replicates the specified partition from the source DC to the destination DC. You can use this command to force a replication. Note that these three arguments are mandatory. 

An optional switch /full will HWMV and UTDV tables to be reset, replicating all changes from the source DC to the destination DC.

The following command synchronizes the specified DC with all its replication partners. You can specify a partition to replicate; if nothing is specified, the Configuration partition is used by default

Instead of specifying a partition the /A switch can be used to sync all partitions held by the DC. By default only partner DCs in the same site are replicated with, but the /e switch will cause replication to happen with all partners across all sites. Also, changes can be pushed from the DC to others rather than pulled (the default) using the /P switch. 

Notes on AD Replication (contd.)

This post is a continuation to my previous one

How the AD Replication Model Works

(source)

Conflict Resolution

Previously I mentioned that conflict resolution in AD does not depend on timestamp. What is used instead of the “volatility” of changes. Here’s how it works in practice. 

Remember the replication metadata stored on each object? The ones you can view using repadmin /showobjmeta. I mentioned 5 metadata there – the Local USN, the Originating DSA, the Originating USN, the Originating Timestamp, and Version. Three of these metadata are used a conflict resolution stamp for every attribute:

  • Version, which as we know is updated each time the attribute is updated
  • Originating Timestamp, which is the timestamp from the DC where the update originated from
  • Originating DSA, which is not the DSA name or GUID as you’d expect from the repadmin output, but the invocationID of the DSA where the update originated from.

How is this stamp used? If there’s a conflict to an attribute – i.e. a change is made to an attribute on two separate DCs – first the Version is considered. Whichever update has the higher Version wins. Notice how the timestamp of the change doesn’t matter. Say WIN-DC01 had a change to an attribute twice (thus incrementing the Version twice) while WIN-DC02 had a change to the same attribute once, but at a later time, and both these changes reached WIN-DC03 together – the change from WIN-DC01 will win over the later change from WIN-DC02 because the number of changes were more there. 

If two conflicting changes have the same Version then the timestamp is considered. This has a one-second resolution, and so unless the conflict changes happened at the exact same second this is usually enough to resolve the conflict. 

However, if both Version and timestamp are unable to resolve the conflict, then the invocationID is considered. This is guaranteed to be different for each DC, and is random, so whichever change is from a DC with higher invocationID wins. 

Replication Metadata

The Knowledge Consistency Checker (KCC) (will be discussed in a later post) is the component that is responsible for maintaining the replication topology. It is maintains connection objects with the replication partners and stores this information, for each domain partition, in a multivalued attribute called repsFrom in the root of that domain partition. 

For example, here are the replication partners for WIN-DC02. Although not shown here, WIN-DC04 & WIn-DC05 are of a child domain. 

win-dc02-replications

Now consider the repsFrom attribute of the domain partition on WIN-DC02: 

And here’s the repsFrom from the Configuration partition:

Each entry starts from dwVersion and contains information like the number of failures, time of last successful sync, the DSA GUID, the database GUID, USNs, etc. Since only one DC is replicating with WIN-DC02 for the domain partition there’s only one value for that partition; while there are three DCs replicating for the Configuration partition and so there are three values for that partition. 

Each DC polls the DSAs (DCs) in this attribute for changes (that’s for the scheduled changes, not the ones where the source DC sends and update to all its partners and they poll for changes). If a DC is demoted – i.e. its NTDS settings object is deleted (i.e. the DSA is no longer valid) – the KCC will remove this DSA from the attribute. This prevents replication attempts to demoted DCs. (Prior to Windows 2003 though, and even now if this attribute is assigned a value, there used to be an attribute called replTopologyStayOfExecution. This value had a default of 14 days, and a maximum value of half the tombstone lifetime (the period for which deleted objects are retained). In the presence of this attribute – which existed by default in Window Server 2003 and prior, and can be set if required in later versions – if the KCC detects an invalid DSA, instead of removing it from the repsFrom attribute it will let it remain until such time the duration of the object being deleted exceeds replTopologyStayOfExecution). 

Atomicity

Atomicity is a term encountered in databases and operating systems (I first encountered it during my CS classes, specifically the OS course I think). An atomic operation can be thought of as an indivisible operation – meaning all events that take place during an atomic operation either take place together, or they don’t. (It comes from the idea that an atom was thought to be indivisible). With respect to databases, this is a guarantee that if a bunch of values are written in an atomic operation, either all the values are written or none of them. There’s no confusion that perhaps only a few values got committed while the rest were missed out. Even if one value didn’t get written, all others will not be written. That’s the guarantee! 

In the context of AD, updates are written to the AD database. And all attribute updates to a single object will be written atomically in a single transaction. However:

  • If the attributes are linked attributes (remember the previous post where there are attributes with forward and back links, for e.g. member and memberOf) the updates won’t be atomic – not too surprising, they are for different objects after all, and also usually the back link is generated by the system not sent as an update. 
  • Remember: the maximum number of values that can be written in a single transaction is 5000. 
  • To ensure that (nonlinked) attributes to an object are written atomically, updates to nonlinked attributes are prioritized over updates to linked attributes. This happens when a source DC packages all the updates into replication packets. The DC prioritizes nonlinked attributes over linked attributes. When it comes to writing the updates to the destination DC database though:
    • For linked attributes, because of parent-child relationships the objects might be written out of order to how the updates are received. This is to ensure that objects are created before any links are applied to that object.
    • When an object already exists on the destination DC, even though nonlined attributes are replicated first, they are not guaranteed to be written first to the database. Generally they are applied first, but it’s not guaranteed. (Note to self: I am not very clear about this point)
  • Remember: the number of values in a replication packet is approximately 100. If there are more than 100 values, again the nonlinked attributes are tried to put in one packet, while the linked attributes can span multiple packets. In such cases, when they are written on the destination DC database, all updates to a single object can require multiple transactions. (They are still guaranteed to be written in the same replication cycle). 
  • Note: Only originating updates must be applied in the same database transaction. Replicated updates can be applied in more than one database transaction.

 

Notes on AD Replication, Updates, Attributes, USN, High-Watermark Vector, Up-to-dateness Vector, Metadata, etc.

Reading a couple of AD Replication posts from TechNet/ MSDN. Below are my notes on them. 

Note

This is a super long post! It began as notes to the TechNet/ MSDN posts but it quickly grew into more. Lots of additional stuff and examples from my side/ other blog posts. Perhaps I should have split these into separate posts but I didn’t feel like it.

What is the AD Replication Model?

(source)

  • AD makes use of pull replication and not push. That is, each DC pulls in changes from other DCs (as opposed to the DC that has changes pushing these to targets). Reason for pulling instead of pushing is that only the destination DC knows what changes it needs. It is possible it has got some changes from another DC – remember AD is multimaster – so no point pushing all changes to a destination DC.
  • Initial replication to a new DC in the domain is via LDAP. Subsequent replications are via RPC.
  • All DCs do not replicate with all other DCs. They only replicate with a subset of DCs, as determined by the replication topology. (I am not sure, but I think this is only in the case of InterSite replication …). This is known as store and forward replication. DCs store updates they get from replication partners ams forward these to other DCs.
  • There are two sorts of replication – state-based and log-based.
    • State-based means DCs apply updates to their replicas (their copies of the partitions) as and when they arrive.
    • In log-based replication each DC maintains a log of the changes and sends this log to all other DCs. Once a destination DC receives this log it applies it to its replica and becomes up-to-date. This also means the destination DC will receive a list of all changes (from the source DC perspective), not just the changes it wants. 
    • Active Directory (actually called Active Directory Domain Services since Server 2008) uses state-based replication. 
    • Each DC maintains a list of objects by last modification. This way it can easily examine the last few objects in the list to identify how much of the replication source’s changes have already been processed. 

Linked & Multivalued attributes

Before the next post it’s worth going into Linked attributes and Multivalued attributes.

  • Linked attributes are pairs of attributes. AD calculates the value of one of the attributes (called the “back link”) based on the value of the other attribute (called the “forward link”). For example: group membership. Every user object has an attribute called memberOf. You can’t see this by default in ADUC in the “Attribute Editor” tab. But if you click “Filter” and select to show “Backlinks” too then you can view this attribute. backlinks The memberOf attribute is an example of a back link. And it’s generated by AD, which is why it’s a read-only attribute. It’s counterpart, the forward link, is the member attribute of a group object. Linked attributes are linked together in the schema. In the schema definitions of those attributes – which are instances of an attributeSchema class – there is a linkID attribute that defines the back and forward links. The attribute with an even linkID is the forward link (the write-able attribute that we can set) while the attribute with a linkID that’s one more than the linkID of the forward link is the back link (the read-only, AD generated attribute). For instance, using ADSI Edit I found the CN=Member,CN=Schema,CN=Configuration,DC=mydomain object in the Schema partition. This is the schema definition of the member attribute. Being a forward link it has an even linkID. linkid Its counterpart can be easily found using ldp.exe. Search the Schema partition for all objects with linkID of 3. linkid-2 The result is CN=Is-Member-Of-DL,CN=Schema,CN=Configuration,DC=mydomain, which is the attributeSchema object defining the memberOf attribute (notice the lDAPDisplayName attribute of this object in the above screenshot).
    • It’s worth taking a moment to understand the above example. When one uses ADUC to change a user/ group’s group membership, all one does is go to the user/ group object, the “Member Of” tab, and add a group. This gives the impression that the actual action happens in the user/ group object. But as we see above that’s not the case. Although ADUC may give such an impression, when we add a user/ group to a group, it is the group that gets modified with the new members and this reflects in the user/ group object that we see. ADUC makes the change on the user/ group, but the DSA makes the real change behind the scenes. The cause and effect is backwards here …
    • Another obvious but not so obvious point is that when you add a user/ group to a group, it is the group’s whenChanged attribute that gets changed and it is the change to the group that is replicated throughout the domain. The user object has no change and nothing regarding it is replicated. Obvious again, because the change really happens on the group and the effect we see on the user/ group is what AD calculates and shows us. 
  • Multivalued attributes, as the name suggests, are attributes that can hold multiple values. Again, a good example would be group membership. The member and memberOf attributes mentioned above are also multivalued attributes. Obvious, because a group can contain multiple members, and a user/ group can be a member of multiple groups. Multivalued attributes can be identified by an attribute isSingleValued in their attributeSchema definition. If this value is TRUE it’s a single valued attribute, else its a multivalued attribute.

How the AD Replication Model Works

(source)

A must read post if you are interested in the details! 

On replication

  • AD objects have attributes. AD replicates data at the attribute level – i.e. only changes to the attributes are replicated, not the entire object itself. 
    • Attributes that cannot be changed (for e.g. back links, administrative attributes) are never replicated. 
  • Updates from the same directory partition are replicated as a unit to the destination DC – i.e. over the same network connection – to optimize network traffic.
  • Updates are always specific a single directory partition. 
  • Replication of data between DCs consist of replication cycles (i.e. the DCs keep replicating until all the data has replicated). 
    • There’s no limit to the number of values that can be transferred in a replication cycle. 
    • The transfer of data happens via replication packets. Approximately 100 values can be transferred per packet. 
      • Replication packets encode the data using ASN.1 (Abstract Syntax Notation One) BER (Basic Encoding Rules). Check out Wikipedia and this post for more information on ASN.1 BER (note: ASN.1 defines the syntax; BER defines the encoding. There are many other encodings such as CER, DER, XER but BER is what LDAP uses). See this blog post for an example LDAP message (scroll down to the end). 
    • Once a replication cycle has begun, all updates on the source DC – including updates that occur during the replication cycle – are send to the destination DC. 
    • If an attribute changes multiple times between replication cycles only the latest value is replicated. 
    • As soon as an attribute is written to the AD database of a DC, it is available for replication. 
  • The number of values that can be written in a single database transaction (i.e. the destination DC has all the updates and needs to commit them to the AD database) is 5000. 
    • All updates to a single object are guaranteed to be written as a single database transaction. This way the state of an object is always consistent with the DC and there are no partially updated objects. 
      • However, for updates to a large number of values to multivalued attributes (e.g. the member attribute from the examples above) the update may not happen in the same transaction. In such cases the values are still guaranteed to be written in the same replication cycle (i.e. all updates from the source DC to that object will be written before the DC performs another replication cycle). (This exception for multivalued attributes is from Server 2003 and above domains, I think).
    • Prior to Windows Server 2003, when a multivalued attribute had a change the entire attribute was replicated (i.e. the smallest change that could be replicated was an attribute). 
      • For example, if a multivalued attribute such as member (referring to the members of a group) had 300 entries and now an additional entry was added, all 301 entries were replicated rather than just the new entry. 
      • So if a group had 5000 members and you added an extra member, 5001 entries were replicated as updates to its member attribute. Since that is larger than the number of values that can be committed in a single transaction, it would fail. Hence the maximum number of members in a group in a Windows 2000 forest functional level domain was 5000. 
    • Starting from Windows Server 2003, when a multivalued attribute has a change only the changed value is replicated (i.e. the smallest change that can be replicated is a value). Thus groups in Windows Server 2003 or Windows Server 2003 interim functional level domains don’t have the limitation of 5000 members. 
      • This feature is known as Linked Value Replication (LVR). I mentioned this in an earlier post of mine in the context of having multiple domains vs a single domain. Not only does LVR remove limitations such as the above, it also leads to efficient replication by reducing the network traffic.
      • When a Windows 2000 forest level domain is raised to Windows 2003/ 2003 interim forest level, existing multivalued attributes are not affected in any way. (If they were, there’d be huge network traffic as these changes propagate through the domain). Only when the multivalued attribute is modified does it convert to a replicate as single values. 
  • Earlier I mentioned how all attributes are actually objects of the class attributeSchema.  The AD schema is what defines attributes and the relations between them.
    • Before replication between two DCs can happen, the replication system (DRS – see below) checks whether the schema of both DCs match. If the schemas do not match, replication is rescheduled until the schemas match (makes sense – if replication happens between DCs with different schemas, the attributes may have different meanings and relationships, and replication could mess things up). 
    • If the forest schema is changed, schema replication takes precedence over all other replication. In fact, all other replication is blocked until the schema replicates. 

Architecture

  • On each DC, replication operates within the Directory System Agent (DSA) component – ntdsa.dll
    • DSA is the interface through which clients and other DCs gain access to the AD database of that DC. 
    • DSA is also the LDAP server. Directory-aware applications (basically, LDAP-aware applications) access DSA via the LDAP protocol or LDAP C API, through the wldap32.dll component  (am not very clear about this bit). LDAPv3 is used. 
  • A sub-component of the DSA is DRS (Directory Replication System) using the DRS RPC protocol (Microsoft’s specification of this protocol can be found at this MSDN link). Client & server components of the DRS interact with each other to transfer and apply updates between DCs. 
    • Updates happen in two ways: via RPC or SMTP (the latter is only for non-domain updates, which I infer to mean Schema or Configuration partition updates) 
    • Domain joined computers have a component called ntdsapi.dll which lets them communicate with DCs over RPC.
      • This is what domain joined computers use to communicate with the DC.
      • This is also what tools such as repadmin.exe or AD Sites and Services (dssites.msc) use to communicate with the DC (even if these tools are running on the DC). 
    • DCs additionally have a private version of ntdsapi.dll which lets them replicate with other DCs over RPC. (I infer the word “private” here to mean it’s meant only for DCs).
      • As mentioned earlier, DC to DC replication can also bypass RPC and use SMTP instead. Then the ntdsapi.dll component is not used. Other components, such as ISMServ.exe and the CDO library are used in that case. Remember: this is only for non-domain updates. 
    • The RPC interface used by DRS is called drsuapi. It provides the functions (also see this link) for replication and management. Check this section of the TechNet post for an architecture diagram and description of the components. 
      • The TechNet post also mentions DRS.idl. This is a file that contains the interface and type library definitions. 
  • The DSA also has a sub-component for performing low-level operations on the AD database. 
  • The DSA also has a sub-component that provides an API for applications to access the AD database. 
    • The AD database is called ntds.dit (DIT == Directory Information Tree; see this link for more info). The database engine is Extensible Storage Engine (ESE; esent.dll)

Characteristics of AD replication

  • Multimaster
    • Changes can be made to any DCs (as long as they are authoritative for the objects).
  • Pull
    • When an update occurs on a DC it notifies its partners. The partners then requests (pulls) changes from the source DC. 
  • Store-and-forward
    • When a DC receives a change from its partners, it stores the change and in-turn forwards on to others (i.e. informs others so they can issue pull requests from itself). Thus, the DC where a change is made does not have to update every other DCs in the domain. 
    • Because of the store-and-forward mechanism replication must be thought of as sequentially moving through the domain. 
  • State-based
    • Each DC has metadata to know the “state” of its replicas. This state is compared with that of its partner to identify the changes required. (This is in contrast to log-based replication where each DC keeps a log of changes it made and sends that log to its partners so they can replay the log and update themselves). 
    • This makes uses of metadata such as Update Sequence Number (USN), Up-to-dateness vector, and High-watermark vector. Synchronized time is not primarily used or required to keep track of this (it is used, but in addition to other mechanisms). 

Updates

LDAP/ AD supports the following four types of update requests:

  • Add an object to the directory.
  • Delete an object from the directory. 
  • Modify (add, delete, remove) attribute values of an existing object in the directory. 
  • Move an object by changing the name or parent of the object. 

Each of the above update requests generates a separate write transaction (because remember, all updates to a single object happen in a single transaction). Updates are an all-or-nothing event. If multiple attributes of an object are updated, and even one of those updates fail when writing to the database, all attributes fail and are not updated. 

Once an update request is committed to the database it is called an originating update. When a DC receives an originating update, writes it to its database, and sends out updates to other DCs these are called replication updates. There is no one-to-one relation between originating updates and replication updates. For instance, a DC could receive multiple originating updates to an object – possible even from different DCs – and then send a replication update with the new state of that object. (Remember: AD is state-based, not log-based. It is the state that matters, not the steps taken to reach that state). 

Adding request:

  • Creates a new object with a unique objectGUID attribute. Values of all replicated attributes are set to Version = 1. (The Version attribute will be discussed later, below). 
  • The add request fails if the parent object does not exist or the DC does not contain a writeable replica of the parent object’s directory partition. 

Modify request:

  • If an attribute is deleted then its value is set with NULL and Version is incremented. 
  • If values are to be added/ removed from an attribute, it is done so and the attribute Version is incremented. The Modify request compares the existing and new values. If there are no changes then nothing happens – the request is ignored, the Version does not change. 

Move request:

  • This is a special case of the Modify request in that only the name attribute is changed. 

Delete request:

  • The isDeleted attribute is set to TRUE. This marks the object as tombstoned (i.e. deleted but not removed from AD). 
  • The DN of the object is set to a value that cannot be set by an LDAP application (i.e. an impossible value). 
  • Except a few important attributes, the rest are stripped from the object (“stripped”, not removed as one would do above). 
  • The object itself is moved to the Deleted Objects container. 

Certain objects are protected from deletion:

  • Cross-references (class crossRef) and RID Object for the DC. Any delete request for these objects are rejected. And any originating update deletion of these objects is rejected, and all attributes of the object are updated (Version incremented) so the object replicates to other DCs and is reanimated wherever it was deleted.  
    • Cross-references are present in the Configuration partition: CN=Partitions,CN=Configuration,DC=(domain)
    • RID Objects are present under each DC at CN=RID Set,CN=(DC),OU=Domain Controllers,DC=(domain)
  • The NTDS Settings (class nTDSDSA) object.
    • This object represents the DSA (Directory System Agent). It is present in the Configuration partition under the site and DC: CN=NTDS Settings,CN=(DC),CN=Servers,CN=(SITE),CN=Sites,CN=Configuration,DC=(domain)
    • Remember, the DSA is the LDAP server within the DC. The DSA’s GUID is what we see when DCs replicate or in their DNS names (DSAGUID._msdcs.domain is a CNAME to the DC name).
    • The objectGUID of the DC object is not the same as the objectGUID of its DSA object. The latter is what matters. When a DC computer object is opened in ADUC, it is possible to view the corresponding DSA object by clicking on the “NTDS Settings” button in the first tab. 
    • Trivia: to find all the DCs in a forest one can query for objects of class nTDSDSA. Below query, for instance, finds all objects of that class and returns their DN and objectGUID

      nTDSDSA

    • When a DC is demoted, its DSA object is deleted but not really deleted. It is protected and disabled from receiving replication requests. Thus, a query such as the above will return DSA objects of DCs that may no longer exist in the forest.

      A better way to structure the above query then would be to also filter out objects whose isDeleted attribute is not TRUE.

      nTDSDSA-2

Conflicts

AD does not depend on timestamps to resolve conflicts. In case of conflicts the “volatility” of changes is what primarily matters. That is, if an attribute was updated twice on one DC and thrice on another DC, even if the timestamps of changes from the first DC are later than the second DC, the change from the second DC will win because the attribute was updated thrice there. More on this in my next post

Database GUID

I mentioned above that each DSA has its own objectGUID. This GUID is created with the server is promoted to a DC and deleted (sort of) when the DC is demoted. Thus the GUID is present for the lifetime of the DC and doesn’t change even if the DC name changes. 

The AD database (ntds.dit) on each DC has its own GUID. This GUID is stored in the invocationId attribute of the DSA. Unlike the DSA GUID, the database GUID can change. This happens when (1) the DC is demoted and re-promoted (so the database changes), (2) when an application NC is added/ removed to the DC, (3) when the DC/ database is restored from a backup, or (4) (only in Server 2012 and above) whenever a DC running in a VM is snapshotted or copied.

The invocationId attribute can be viewed via ldp.exe as above, or in the “NTDS Settings” of the DC computer object in AD Users & Computers, or in the “NTDS Settings” in AD Sites & Services. It can also be viewed in the output of repadmin.exe.

The invocationID is a part of replication requests (more later). When the invocationID changes other know that they have to replicate changes to this DC so it can catch up. The first DC in a domain will have its invocationID and objectGUID as same (until the invocationID changes). All other DCs will have different values for these both. 

Update Sequence Numbers (USNs)

(I was planning on covering this separately as part of my AD Troubleshooting WorkshopPLUS posts, but USNs are mentioned in this TechNet post so I might as well cover them now). 

USNs are 64-bit counters maintained on each DC. The number is different for each DC and is stored in the highestCommittedUsn attribute of the rootDSE object.

rootDSE is an imaginary object. It is the root of the directory namespace. Under it we have the various domain partitions, configuration partition, schema partition, and application partitions. rootDSE can be queried to find the various partitions known to the DC. It can be viewed through ADSI Edit or ldp.exe (the latter makes it easier to view all the attributes together).

rootDSE

As can be seen in the screenshot above, one of the attributes is highestCommittedUSN.

Each time a DC commits an update (originating update/ replication update), it updates the highestCommittedUSN attribute. Thus the USN is associated with each successful transaction to the AD database. Remember: all updates to a single object are written in a single transaction, so a USN is essentially associated with each successful update to an object – be it a single attribute, or multiple updates to the same/ multiple attributes (but all written in the same transaction). 

USNs are update incrementally for each write transaction. So, for example, when I took the above screenshot the USN for WIN-DC02 was 77102. When I am writing this paragraph (the next day) the USN is 77230. This means between yesterday and today WIN-DC02 has written 128 transactions (77230-77102) to its database.  

Every attribute of an object has a USN associated with it. This is a part of the replication metadata for that object, and can be viewed through the repadmin.exe command. For instance, using the /showobjmeta switch (note that here we specify DC first and then object):

Notice how the attribute USNs vary between the two DCs. Also notice the metadata stored – the Local USN, the originating DSA, the Originating DSA's USN, the timestamp of the update, and Version. If you are running the above command it is best to set the command prompt window width to 160, else the output doesn’t make much sense. I will talk about Local USN and Originating USN in a moment. 

Another switch is /showmeta (here we specify the object first and then the DC):

Both switches seem to produce the same output. The important items are the Local USN and Originating USN, and the Version

  • Version starts from 1 and is incremented for each update. Version will be same on all DCs – when an DC commits an update request (originating update or replication update) it will increment the Version. Since all attributes start with the same Version = 1, the current value will be the same on all DCs. 
  • Local USN is the USN value for that attribute on the DC we are looking at. It is the value of the highestCommittedUSN for the transaction that committed the update to this attribute/ set of attributes
  • Originating USN is the USN for that attribute on the DSA where the originating update was sent from.

For instance: the attribute description. WIN-DC01 has local USN 46335, WIN-DC02 has 19340, and WIN-DC03 has 8371. The latter two DCs got their update for this attribute from WIN-DC01 so they show the originating DSA as WIN-DC01 and the Originating USN as 46335.

Every object has an attribute called uSNChanged. This is the highest Local USN among all the attributes of that object. (What this means is that from the USN of an object we can see which of its attributes have the same local USN and so easily determine the attributes changed last). Unlike the attribute USNs which are metadata, uSNChanged is an object attribute and thus can be viewed via ADSI Edit or ADUC. From the command line, repadmin.exe with the /showattr switch can be used to view all attributes of an object (this switch takes the DC name first, then the object). 

Above output tells me that on WIN-DC01 the uSNChanged for this object is 46335.  From the earlier /showobjmeta output I know that only the description attribute has that local USN, so now I know this was the last attribute changed for this object. 

So, to recap: DCs have a USN counter stored in highestCommitedUSN attribute. This counter is updated for each successful write transaction to the database. Since writes happen per object, it means this USN is updated every time an object is updated in the database. Each object attribute has its own USN – this too is per DC, but is not an attribute, it is metadata. Finally, each object has a uSNChanged attribute which is simply the highest attribute USN of that object. This too is per DC as the attribute USN is per DC. The DC’s highestCommittedUSN attribute and an object’s uSNChanged attribute are related thus: 

  • When an attribute update is committed to the database the DC’s highestCommittedUSN is incremented by 1.
  • The Local USN of the attribute/ attributes is set to this new highestCommittedUSN
  • This in turns updates the object’s uSNChanged to be the new highestCommittedUSN (because that is the highest attribute Local USN now)

Thus, the highestCommittedUSN is the highest uSNChanged attribute among all the replicas held by the DC.  

Here’s an example. First I note the DC’s highestCommitedUSN (I have removed the other attributes from the output). 

Then I note an object’s uSNChanged:

Now I connect via ADUC and change the description field. Note the new USN. 

And note the DC’s USN:

It has increased, but due to the other changes happening on the DC it is about 10 higher than the uSNChanged of the object I updated. I searched the other replicas on my DC for changes but couldn’t find anything. (I used a filter like (uSNChanged>=125979) in ldp.exe and searched every replica but couldn’t find any other changes. Maybe I missed some replica – dunno!) This behavior is observed by others too. (From the previous linked forum post I came across this blog post. Good read).  

Finally, I must point out that even though I said the attribute metadata (Local USN, Originating USN, Originating DSA, Originating Time/ Date, Version) are not stored as attributes, that is not entirely correct. Each object has an attribute called replPropertyMetaData. This is an hexadecimal value that contains the metadata stored as a binary value. In fact, if we right click on an object in ldp.exe it is possible to view the replication metadata because ldp.exe will read the above attribute and output its contents in a readable form. 

ldp-metadata

Bear in mind this attribute is not replicated. It is an attribute that cannot be administratively changed, so can never be updated by end-users and doesn’t need replicating. It is only calculated and maintained by each DC. uSNChanged is a similar attribute – not replicated, only administratively changed. 

Note to self: I need to investigate further but it looks like uSNChanged cannot be viewed by ldp.exe for all objects. For instance, ldp.exe shows this attribute for one user object in my domain but not for the other! I think that’s because the attribute is generated by the AD tools when we view it. repadmin.exe and the GUI tools show it always. Similarly, the attribute level metadata attribute too cannot be viewed by ldp.exe for all objects. For some objects it gives an error that the replPropertyMetaData attribute cannot be found and so cannot show the replication metadata. This could also be why there was a gap between the uSNChanged and highestCommittedUSN above. 

High-watermark Vector (HWMV) & Up-to-dateness Vector (UTDV)

To recap once more, what we know so far is:

  • Every attribute has replication metadata that contains its Local USN, the originating DSA's USN, the originating DSA, the timestamp, and Version
  • The highest Local USN of an attribute is stored as the object’s uSNChanged attribute. 
  • The highest uSNChanged attribute among all objects on all replicas held by the DSA is stored as its highestCommittedUSN attribute in the rootDSA
  • All these USN counters are local to the DC (except for the Originating USN which is local to that the originating DSA). 

How can DCs replicate with each other using the above info? Two things are used for this: High-watermark vector and Up-to-dateness vector. 

The HWMV is a table maintained on each DC.

  • There is one table for each directory partition the DC holds replicas for (so at minimum there will be three HWMV tables – for the domain partition, the Schema partition, and the Configuration partition). 
  • The HWMV table contains the highest USN of the updates the DC has received from each of its replication partners for that replica. Note: the table contains the USN that’s local to the replication partner.
  • Thus the HWMV can be thought of as a table contain the highest uSNChanged value for each directory partition of its replication partners when they last replicated.

Got it? Now whenever a DC needs to replicate with another DC, all it needs to do is ask it for each of the changes since the last uSNChanged value the destination is aware of! Neat, right! The process looks roughly like this:

  1. The originating DC will have some changes. These changes will cause uSNChanged values of the affected objects to change. The highestCommittedUSN of the DC too changes. All these are local changes.
  2. Now the DC will inform all its replication partners that there are changes. 
  3. Each of these replication partners will send their HWMV for the partition in question.
  4. From the received HWMV table, the originating DC can work what changes need to be sent to the destination DC. 
    1. The originating DC now knows what USNs it needs to look for. From this it knows what objects, and in turn which of their attributes, were actually changed. So it sends just these changed attributes to the destination DC. 

To make the process of replication faster, all DCs have one more table. That is the Up-to-dateness Vector (UTDV).

  • Like the HWMV, this too is for every replica the DC holds. 
  • Unlike the HWMV this contains the highest USN of the updates the DC has received from every other DC in the domain/ forest for that replica. 
  • The table also contains the timestamp of last successful replication with each of those DCs for that replica.

The UTDV table has a different purpose to the HWMV. This table is sent by the destination DC to the originating DC when it requests for changes – i.e. in step 3 above.

When the originating DC gets the UTDV table for its destination DC, it can look at the table and note the destination DC’s highest received USNs for that partition from other DCs. Maybe the destination DC has asked for changes from USN number x upwards (the USN number being of the originating DC). But these changes were already received by the destination DC from another DC, under USN number y and upwards (the USN number being of that other DC). The destination DC does not know that the changes requested by USN x and upwards are already with it from another DC, but by looking at the UTDV table the originating DC can see that USNs y and above already contain the changes the destination DC is requesting, so it can filter out those updates when sending. (This feature is called “propagation dampening”). 

  • In practice, once the originating DC compiles a list of USNs that need to be sent to the destination DC – at step 4 above – it goes through its replication metadata to check each attribute and the originating DSA and originating USN associated with that attribute.
  • The originating DC then looks at the UTDV table of the destination DC, specifically at the entry for the DC that had sent it an update for the changed attribute. (This DC could be same as the originating DC). From the table it can see what USNs from this DC are already present at the destination DC. If the USN value in the table is higher than the USN value of the attribute, it means the destination DC already has the change with it. So the originating DC can filter out these and similar attributes from sending to the destination DC.  

Thus the UTDV table works along with the HWMV table to speed up replication (and also avoid loops wherein one DC updates another DC who updates the first DC and thus they keep looping). And that is how replications happen behind the scenes! 

Once a destination DC updates itself from an originating DC – i.e. the replication cycle completes – the source DC sends its UTDV table to the destination DC. The destination DC then updates its UTDV table with the info from the received UTDV table. Each entry in the received table is compared with the one it has and one of the following happens:

  • If the received table has an entry that the destination DC’s UTDV table does not have – meaning there’s another DC for this replica that it isn’t aware of, this DC has replicated successfully with the originating DC and so all the info it has is now also present with the destination DC, and so it is as good as saying this new DC has replicated with the destination DC and we are aware of it the same way the originating DC is aware – so a new entry is added to the destination DC’s UTDV table with the name of this unknown DC and the corresponding info from the received UTDV table. 
  • If the received table has an entry that the destination DC’s UTDV table already has, and its USN value is higher than what the destination DC’s table notes – meaning whatever changes this known DC had for this partition has already replicated with the originating DC and thus the destination DC – and so its entry in the UTDV can actually be updated, the UTDV table for that server is updated with the value from the received UTDV table.  

The UTDV table also records timestamps along with the USN value. This way DCs can quickly identify other DCs that are not replicating. These timestamps record the time the DC last replicated with the other DC – either directly or indirectly. 

Both HWMV and UTDV tables also include the invocationID (the database GUID) of the DCs. Thus, if a DC’s database is restored and its invocationID changes, other DCs can take this into account and replicate any changes they might have already replicated in the past.  

From the book I am reading side-by-side (excellent book, highly recommended!) I learnt that apart from the HWMV and UTDV tables and the naming context it wants to replicate, the destination DC also sends two other pieces of info to originating DC. These are: (1) the maximum number of object updates the destination DC wishes to receive during that replication cycle, and (2) the maximum number of values the destination DC wishes to receive during that replication cycle. I am not entirely clear what these two do. Once a replication cycle begins all object updates and values are sent to the destination DC, so the two pieces above seems to be about whether all the updates are sent in one replication packet or whether they are split and sent in multiple packets. The maximum number of values in a single packet is about 100, so I guess these two numbers are useful if you can only accept less than 100 values per packet – possibly due to network constraints. 

More later …

Unfortunately I have to take a break with this post here. I am about halfway down the TechNet post but I am pressed for time at the moment so rather than keep delaying this post I am going to publish it now and continue with the rest in another post (hopefully I get around to writing it!). As a note to myself, I am currently at the Active Directory Data Updates section, in the sub-section called “Multimaster Conflict Resolution Policy”.

Active Directory: Troubleshooting with DcDiag (part 2)

Continuing from here

LocatorCheck

  • Checks whether DCs have certain required knowledge/ ability. Specifically, whether the DC that’s tested knows of or can be a:
    • The Global Catalog (GC)
    • The Primary Domain Controller (PDC)
    • Kerberos Key Distribution Centre (KDC)
    • Time Server
    • Preferred Time Server
  • By itself the test doesn’t output much info:

    To get more details one has to use the /v switch. Then output similar to the following will be returned:

    Note that the DC itself needn’t be offering one of the servers. But it must know who else offers these and be able to refer. For instance, in the case of my domain WIN-DC03 (the server I am testing against) isn’t a GC or PDC so it returns WIN-DC01 as these. It is a time server, but is not a preferred time server (as that’s the forest root domain PDC), so the output is accordingly.

Intersite

  • Checks for failures that could affect Intersite replication.
  • Warning: By default the test silently skips doing anything and simply returns a success! Note the output below:

    As you can see from the verbose output the test actually does nothing.

  • To make the test do something one must specify the /a or /e switches (all DCs in the site or all DCs in the enterprise, respectively).

    Now WIN-DC02 is flagged as having issues. The /e will throw even more light:

    (In this case the router between the two sites was shutdown and so Intersite replication was failing. Hence the errors above.

  • This test doesn’t seem to force an Intersite replication. It only connects to the servers and checks for errors, I think. For instance, when I turned on the router above and verified the two DCs can see each other, forced an enterprise wide replication (repadmin /syncall win-dc01 /e /A) (tell WIN-DC01 to ask all its partners to replication, enterprise-wide, all NCs), and double checked the replication status (repadmin.exe /showrepl WIN-DC01) – everything was working fine, but the Intersite test still complains. Not the same errors as above, but different errors. The test passes but there are warnings that each site doesn’t have a Bridgehead yet because of errors. After about 15 mins the errors clears.
  • Intersite replication, Bridgeheads, and InterSite Topology Generators (ISTG) are part of later posts.

KccEvent

  • Checks whether the Knowledge Consistency Checker (KCC) has any errors. 
  • This test only checks the “Directory Services” event log of the specified server for any errors in the last 15 mins. (If you run the test with the /v switch it even says so). 

KnowsOfRoleHolders

  • Checks whether the DC knows of various Flexible Single Master Operations (FSMO) role holders in the domain. (FSMO is part of a later post so I won’t elaborate it here). 
  • By default the answer is just a pass or fail. 
  • Use with the /v switch to know what the DC thinks it knows: 
  • Good test to run after a role change to see whether all DCs in the domain/ enterprise know of the new role holder.

MachineAccount

  • Checks whether the DC’s machine account exists, is in the Domain Controllers OU, and Service Principal Names (SPNs) are correctly registered.
  • This is yet another test that only returns a pass or fail by default. Use with the /v switch to get a list of the registered SPNs.
  • Notice that the CheckSecurityError test also checks SPNs. CheckSecurityError is only run on demand, however.
  • Add the /RecreateMachineAccount switch to recreate the machine account if missing. Note: this does not recreate missing SPNs.
  • Add the /FixMachineAccount switch to fix if the machine account flags are incorrect (am not sure what flags these are …).
  • SPNs can be added/ modified/ deleted using the Setspn command.

NCSecDesc

  • Checks whether all the Naming Contexts on the DC have correct security permissions for replication.

NetLogons

  • Checks whether the Netlogon and SYSVOL shares are available and can be accessed.
  • I pointed out this test previously under the SysVolCheck test. The latter gives the impression it actually checks the SYSVOL shares, but it doesn’t. NetLogons is the one that checks.

ObjectsReplicated

  • Checks whether the DCs machine account and DSA objects have replicated. The DC machine account object is CN=,OU=Domain Controllers,... in the domain NC; the DSA object is CN=NTDS Settings,CN=,CN=Servers,CN=,... in the configuration NC.
  • This test is better run with the /a or /e switches. Without these switches it only checks the DC you test against to see whether it has its own objects. With the switches it checks all the objects for all DCs in the site/ enterprise on all DCs in the site/ enterprise. Which is what you really want.
  • It is also possible to check a specific object via the /objectdn: or limit to DCs holding a specific NC via the /n: switch.

    For example:

    Check all DCs holding the default naming context (rakhesh.local) across all sites:

    Check al DCs holding a specified application NC across all sites:

    I had created the SomeApp2 previously. It is only replicated to the WIN-DC01 and WIN-DC03 servers so the test above will only check those servers. (To recap: you can find the DCs a NC is replicated to from the ms-DS-NC-Replica-Locations attribute of its object in the Partitions container). Note that I had to specify a server above. That’s because without specifying a DC name there’s no way to identify which DCs know of this NC (Note: “know of”, its not necessary they hold the NC, they should only know where to point to). Unlike a domain NC which has DNS entries to help identify the DCs holding it, other NCs have no such mechanism. Below is the error you get if you don’t specify a DC name as above:

    Lastly, it’s also possible to check for the replication status of a specific object. Very useful for testing purposes. Make a test object on one DC, force a replication, wait some time, then test whether that object has replicated to all DCs in your site/ enterprise. (Sure you could connect to each DC via ADUC or ADSIEdit, but this is way more convenient!)

    Below command checks whether the specified user account has replicated to all DCs in the domain:

    I specify a NC above (the /n switch) because I am running DCDiag from a client so I must specify either a server to use (the /s switch) or a NC based on which a DC can be found. If run from a DC then the NC can be omitted.

OutboundSecureChannels

  • Checks whether all DCs in the domain (by default only those in the current site) have a secure channel to DCs in the trusted domain specified by the /testdomain: switch.
  • There seems to be a misunderstanding that this test checks secure channels between DCs of the same domain. That’s not the case, it’s between DCs of two trusted domains.
  • Use the /nositerestriction switch to not limit the test to all DCs in the same site.
  • This test is not run by default. It must be explicitly specified.

RegisterInDNS

  • Checks whether the server being tested can register “A” DNS records. The DNS domain name must be specified via the /DnsDomain: switch.
  • This test is similar to the DcPromo test mentioned previously.
  • This test isn’t run by default.

Replications

  • Checks whether all of the DCs replication partners are able to replicate to it. By default only those in the same site are tested.
  • It contacts each of the partners to get a status update from them. The test also checks whether there’s a replication latency of more than 12 hours.
  • Output from WIN-DC01 in my domain when I disconnected its partner WIN-DC03. WIN-DC02 is not checked as it’s in a different site.

RidManager

  • Checks whether the DC with the RID Master FSMO role is accessible and contains proper information. Use with the /v to get more details on the findings (allocation pool, next available, etc).
  • Example output:

Services

  • Checks whether various AD required services are running the DC.
  • Following services are tested:

    This list is similar (not same!) to the DC critical services list. Notably it doesn’t check if the “DNS Server” and “AD WS” services are running.

SystemLog

  • Checks the System Log for any errors in the last 60 mins (or less if the server uptime is less than 60 mins).

Topology

  • Checks whether the server has a fully connected topology for replication of each of its NCs.
  • Note that the test does not actually check if the servers in the topology are online/ connected. For that use the Replications and CutOffServers tests. This test only checks if the topology is logically fully connected.
  • This test is not run by default. It must be explicitly specified.

VerifyEnterpriseReferences

and

VerifyReferences

  • Checks whether system references required for the FRS and replication infrastructure are present on each DCs. The “Enterprise” variant tests whether references for replication to all DCs in the enterprise are present.
  • Note: I am not very clear what this test does (but feel free to look at Ned’s blog post for more info) and I have been writing this post over many days so I am too lazy to research further either. :) I’ll update this post later if I find more info on the test.
  • This test is not run by default. It must be explicitly specified.

VerifyReplicas

  • Checks whether all the application NCs have replicated to the DCs that should contain a copy.
  • Seems to be similar to the CheckSDRefDom test but more concerned with whether the DCs host a copy or not.
  • This test is not run by default. It must be explicitly specified.

That’s all! Phew! :)

Active Directory: Troubleshooting with DcDiag (part 1)

This post originally began as notes on troubleshooting Domain Controller critical services. But when I started talking about DcDiag I went into a tangent explaining each of its tests. That took much longer than I expected – both in terms of effort and post length – so I decided to split it into a post of its own. My notes aren’t complete yet, what follows below is only the first part.

While writing this post I discovered a similar one from the Directory Services Team. It’s by NedPyle, who’s just great when it comes to writing cool posts that explain things, so you should definitely check it out.

DcDiag is your best friend when it comes to troubleshooting AD issues. It is a command-line tool that can identify issues with AD. By default DcDiag will run a series of “default” tests on the DC it is invoked, but it can be asked to run more tests and also test multiple DCs in the site (the /a switch) or across all sites (the /e switch). A quick glance at the DcDiag output is usually enough to tell me where to look further.

For instance, while typing this post I ran DcDiag to check all DCs in one of my sites:

I ran the above from WIN-DC01 and you can see I was straight-away alerted that WIN-DC03 could be having issues. I say “could be” because the errors only say that DcDiag cannot contact the RPC server on WIN-DC03 to check for those particular tests – this doesn’t necessarily mean WIN-DC03 is failing those tests, just that maybe there’s a firewall blocking communication or perhaps the RPC service is down. To confirm this I ran the same test on WIN-DC03 and they succeeded, indicating that WIN-DC03 itself is fine so there’s a communication problem between DcDiag on WIN-DC01 and WIN-DC03. Moreover, DcDiag from WIN-DC03 can query WIN-DC01 so the issue is with WIN-DC03. (In this particular case it was the firewall on WIN-DC03).

Here’s a list of the tests DcDiag can perform:

Advertising

  • Checks whether the Directory System Agent (DSA) is advertising itself. The DSA is a set of services and processes running on every DC. The DSA is what allows clients to access the Active Directory data store. Clients talk to DSA using LDAP (used by Window XP and above), SAM (used by Windows NT), MAPI RPC (used by Exchange server and other MAPI clients), or RPC (used by DCs/DSAs to talk to each other and replicate AD information). More info on the DSA can be found in this Microsoft document.
  • You can think of the DSA as the kernel of the DC – the DSA is what lets a DC behave like a DC, the DSA is what we are really talking about when referring to DCs.
  • Although DNS is used by domain members (and other DCs) to locate DCs in the domain, for a DC to be actually used by others the DSA must be advertising the roles it provides. The nltest command can be used to view what roles a DSA is advertising. For example:

    Notice the flags section. Among other things the DSA advertises that this DC holds the PDC FSMO role (PDC), is a Global Catalog (GC), and that it is a reliable time source (GTIMESERV). Compare the above output with another DC:

    The PDC, GC, and GTIMESERV flags advertised by WIN-DC01 are missing here because this DC does not provide any of those roles. Being a DC it can act as a time source for domain member, hence the TIMESERV flag is present.

  • When DCs replicate they refer to each other via the DSA name rather than the DC name (further enforcing my point from before that the DSA can be thought of as the kernel of the DC – it is what really matters).

    That is why even though a DC in my domain may have the DNS name WIN-DC01.rakhesh.local, in the additional structure that’s used by AD (which I’ll come to later) there’s an entry such as bdb02ab9-5103-4254-9403-a7687ba91488._msdcs.rakhesh.local which is a CNAME to the regular name. These CNAME entries are created by the Netlogon service and are of the format DsaGuid._msdcs.DNSForestName – the CNAME hostname is actually the GUID of the DSA.

  • If you open Active Directory Sites and Services, drill down to a site, then Servers, then expand a particular server – you’ll see the “NTDS Settings” object. This is the DSA. If you right click this object, go to Properties, and select the “Attribute Editor” tab, you will find an attribute called objectGUID. That is the GUID of the DSA – the same GUID that’s there in the CNAME entry.
    ntds-settings

CheckSDRefDom

Before talking about CheckSDRefDom it’s worth talking about directory partitions (also called as Naming Contexts (NC)).

An AD domain is part of a forest. A forest can contain many domains. All these domains share the same schema and configuration, but different domain data. Every DC in the forest thus has some data that’s particular to the domain it belongs to and is replicated with other DCs in the domain; and other data that’s common to the forest and replicated with all DCs in the forest. These are what’s referred to as directory partitions / naming contexts.

Every DC has four directory partitions. These can be viewed using ADSI Edit (adsiedit.msc) tool.

  • “Default naming context” (also known as “Domain”) which contains the domain specific data;
  • “Configuration” (CN=Configuration,DC=forestRootDomain) which contains the configuration objects for the entire forest; and
  • “Schema” (CN=Schema,CN=Configuration,DC=forestRootDomain) which contains class and attribute definitions for all existing and possible objects of the forest. Even though the Schema partition hierarchically looks like it is under the Configuration partition, it is a separate partition.
  • “Application” (CN=...,CN=forestRootDomain – there can be many such partitions) which was introduced in Server 2003 and are user/ application defined partitions that can contain any object except security principals. The replication of these partitions is not bound by domain boundaries – they can be replicated to selected DCs in the forest even if they are in different domains.
    • A common example of Application partitions are CN=ForestDnsZones,CN=forestRootDomain and CN=DomainDnsZones,CN=forestRootDomain which hold DNS zones replicated to all DNS servers in the forest and domain respectively (note that it is not replicated to all DCs in the forest and domain respectively, only a subset of the DCs – the ones that are also DNS servers).

 

If you open ADSI Edit and connect to the RootDSE “context”, then right click the RootDSE container and check its namingContexts attribute you’ll find a list of all directory partitions, including the multiple Application partitions.

rootDSE

Here you’ll also find other attributes such as:

  • defaultNamingContext (DN of the Domain directory partition the DC you are connected to is authoritative for),
  • configurationNamingContext (DN of the Configuration directory partition),
  • schemaNamingContext (DN of the Schema directory partition), and
  • rootNamingContext (DN of the Domain directory partition for the Forest Root domain)

The Configuration partition has a container called Partitions (CN=Partitions,CN=Configuration,DC=forestRootDomain) which contains cross-references to every directory partition in the forest – i.e. Application, Schema, and Configuration directory partitions, as well as all Domain directory partitions. The beauty of cross-references is that they are present in the Configuration partition and hence replicated to all DCs in the forest. Thus even if a DC doesn’t hold a particular NC it can check these cross-references and identify which DC/ domain might hold more information. This makes it possible to refer clients asking for more info to other domains.

The cross-references are actually objects of a class called crossRef.

  • What the CheckSDRefDom test does is that it checks whether the cross-references have an attribute called msDS-SDReferenceDomain set.
  • What does this mean?
    • An Application NC, by definition, isn’t tied to a particular domain. That makes it tricky from a security point of view because if its ACL has security descriptor referring to groups/ users that could belong to any domain (e.g. “Domain Admins”, “Administrator”) there’s no way to identify which domain must be used as the reference.
    • To avoid such situations, cross references to Application directory partitions contain an msDS-SDReferenceDomain attribute which specifies the reference domain.
  • So what the CheckSDRefDom test really does is that it verifies all the Application directory partitions have a reference domain set.
    • In case a reference domain isn’t set, you can always set it using ADSI Edit or other techniques. You can also delegate this.

CheckSecurityError

  • Checks for any security related errors on the DC that might be causing replication issues.
  • Some of the tests done are:
    1. Verify that KDC is working (not necessarily on the target DC, the test only checks that a KDC server is reachable anywhere in the domain, preferably in the same site; even if the target DC KDC service is down but some other KDC server is reachable the test passes)
    2. Verify that the DC”s computer object exists and is within the “Domain Controllers” OU and replicated to other DCs
    3. Check for any KDC packet fragmentation that could cause issues
    4. Check KDC time skew (remember I mentioned previously of the 5 minute tolerance)
    5. Check Service Principle Name (SPN) registration (I’ll talk about SPNs in a later post; check this link for a quick look at what they are and the errors they can cause)
  • This test is not run by default. It must be explicitly specified.
  • Can specify an optional parameter /replsource:... to perform similar tests on that DC and also check the ability to create a replication link between that DC and the DC we are testing against.

Connectivity

  • This is the only DcDiag test that you cannot skip. It runs by default, and is also run even if you perform a specific test.
  • It tests whether the DSAs are registered in DNS, whether they are ping-able, and have LDAP/ RPC connectivity.

CrossRefValidation

Before talking about CheckRefValidation it’s worth revisiting cross-references and application NCs.

Application NCs are actually objects of a class domainDNS with an instanceType attribute value of 5 (DS_INSTANCETYPE_IS_NC_HEAD | DS_INSTANCETYPE_NC_IS_WRITEABLE).

You can create an application NC, for instance, by opening up ADSI Edit and going to the Domain NC, right click, new object, of type domainDNS, enter a Domain Component (DC) value what you want, click Next, then click “More Attributes”, select to view Mandatory/ Both type of properties, find instanceType from the property drop list, and enter a value of 5.
dnsDomain
dnsDomain2The above can be done anywhere in the domain NC. It is also possible to nest application NCs within other application NCs.

Here’s what happens behind the scenes when you make an application NC as above:

  • The application NC isn’t created straight-way.
  • First, the the DSA will check the cross-references in CN=Partitions,CN=Configuration,DC=forestRootDomain to see if one already exists to an Application NC with the same name as you specified.
    • If a cross-reference is found and the NC it points to actually exists then an error will be thrown.
    • If a cross-reference is found but the NC it points to doesn’t exist, then that cross-reference will be used for the new Application NC.
    • If a cross-reference cannot be found, a new one will be created.
  • Cross references (objects of class crossRef) have some important attributes:
    1. CN – the CN of this cross-reference (could be a name such as “CN=SomeApp” or a random GUID “CN=a97a34e3-f751-489d-b1d7-1041366c2b32”)
    2. nCName – the DN of the application NC (e.g. DC=SomeApp,DC=rakhesh,DC=local)
    3. dnsRoot – the DNS domain name where servers that contain this NC can be found (e.g. SomeApp.rakhesh.local).

      (Note this as it’s quite brilliant!) When a new application NC is created, DSA also creates a corresponding zone in DNS. This zone contains all the servers that carry this zone. In the screenshot below, for instance, note the zones DomainDnsZones, ForestDnsZones, and SomeApp2 (which belongs to a zone I created). Note that by querying for all SRV records of name _ldap in _tcp.SomeApp2.rakhesh.local one can easily find the DCs carrying this partition: dnsRoot For the example above, dnsRoot would be “SomeApp2.rakhesh.local” as that’s the DNS domain name.

    4. msDS-NC-Replica-Locations – a list of Distinguished Names (DNs) of DSAs where this application NC is replicated to (e.g. CN=NTDS Settings,CN=WIN-DC01,CN=Servers,CN=COCHIN,CN=Sites,CN=Configuration,DC=rakhesh,DC=local, CN=NTDS Settings,CN=WIN-DC03,CN=Servers,CN=COCHIN,CN=Sites,CN=Configuration,DC=rakhesh,DC=local). replica-locations Initially this attribute has only one entry – the DC where the NC was first created. Other entries can be added later.
    5. Enabled – usually not set, but if it’s set to FALSE it indicates the cross-reference is not in use
  • Once a cross-reference is identified (an existing or a new one) the Configuration NC is replicated through the forest. Then the Application NC is actually created (an object of class domainDNS object as mentioned earlier with an instanceType attribute value of 5 (DS_INSTANCETYPE_IS_NC_HEAD | DS_INSTANCETYPE_NC_IS_WRITEABLE).
  • Lastly, all DCs that hold a copy of this Application NC have their ms-DS-Has-Master-NCs attribute in the DSA object modified to include a DN of this NC. masterNCs

Back to the CrossRefValidation test, it validates the cross-references and the NCs they point to. For instance:

  • Ensure dnsRoot is valid (see here and here for some error messages)
  • Ensure nCName and other attributes are valid
  • Ensure the DN (and CN) are not mangled (in case of conflicts AD can “mangle” the names to reflect that there’s a conflict) (see here for an example of mangled entries)

CutoffServers

If you open AD Sites and Services, expand down to each site, the servers within them, and the NTDS Settings object under each server (which is basically the DSA), you can see the replication partners of each server. For instance here are the partners for two of my servers in one site:

partners1

partners2

Reason WIN-DC01 has links to both WIN-DC03 (in the same site as it) and WIN-DC02 (in a different site) while WIN-DC03 only has links to WIN-DC01 (and not WIN-DC02 which is in a different site) is because WIN-DC01 is acting as a the bridgehead server. The bridgehead server is the server that’s automatically chosen by AD to replicate changes between sites. Each site has a bridgehead server and these servers talk to each other for replication across the site link. All other DCs in the site only get inter-site changes via the bridgehead server of that site. More on it later when I talk about bridgehead servers some other day … for now this is a good post to give an intro on bridgehead servers.

partners3

WIN-DC02, which is my DC in the other site, similarly has only one replication partner WIN-DC01. So WIN-DC01 is kind of link the link between WIN-DC02 and WIN-DC03. If WIN-DC01 were to be offline then WIN-DC02 and WIN-DC03 would be cut off from each other (for a period until the mechanism that creates the topology between sites kicks in and makes WIN-DC03 the bridgehead server between site; or even forever if I “pin” WIN-DC01 as my preferred bridgehead server in which case when it goes down no one else can takeover). Or if the link that connects the two sites to each other were to fail again they’d be cut-off from each other.

  • So what the CutoffServers test does is that it tells you if any servers are cut-off from each other in the domain.
  • This test is not run by default. It must be explicitly specified.
  • This test is best run with the /e switch – which tells DcDiag to test all servers in the enterprise, across sites. In my experience is it’s run against a specific server it usually passes the test even if replication is down.
  • Also in my experience a server is up and running but only LDAP is down (maybe the AD DS service is stopped for instance) – and so it can’t replicate with partners and they are cut-off – the test doesn’t identify the servers as being cut-off. If the server/ link is down then the other servers are highlighted as cut-off.
  • For example I set WIN-DC01 as the preferred bridgehead in my scenario above. Then I disconnect it from the network, leaving WIN-DC02 and WIN-DC03 cut-off.

    If I test WINDC-03 only it passes the test:

    That’s clearly misleading because replication isn’t happening:

    However if I run CutoffServers for the enterprise both WIN-DC02 and WIN-DC03 are correctly flagged:

    Not only is WIN-DC01 flagged in the Connectivity tests but the CutoffServers test also fails WIN-DC02 and WIN-DC03.

  • The /v switch (verbose) is also useful with this test. It will also show which NCs are failing due to the server being cut-off.

DcPromo

  • Checks whether from a DNS point of view the target server can be made a Domain Controller. If the test fails suggestions given.
  • The test has some mandatory switches:
    • /dnsdomain:...
    • /NewForest (a new forest) or /NewTree (a new domain in the forest you specify via /ForestRoot:...)or /ChildDomain (a new child domain) or /ReplicaDC (another DC in the same domain)
  • Needless to say this test isn’t run by default.

DNS

  • Checks the DNS health of the whole enterprise. It has many sub-tests. By default all sub-tests except one are run, but you can do specific sub-tests too.
  • This TechNet page is a comprehensive source of info on what the DNS test does. Tests include checking for zones, network connectivity, client configuration, delegations, dynamic updates, name resolution, and so on.
  • This test is not run by default.
  • Since it is an enterprise-wide test DcDiag requires Enterprise Admin credentials to run tests.

FrsEvent

  • Checks for any errors with the File Replication System (FRS).
  • It doesn’t seem to do an active test. It only checks the FRS Event Logs for any messages in the last 24 hours. If FRS is not used in the domain the test is silently skipped. (Specifying the /v switch will show that it’s being skipped).
  • Take the results with a pinch of salt. Chances are you had some errors but they are now resolved, but since the last 24 hours worth of logs are checked the test will flag previous error messages. Also, FRS may being used for non-SYSVOL replication and these might have errors but that doesn’t really matter as far as the DCs are concerned.
  • There may also be spurious errors a server’s Event Log is not accessible remotely and so the test fails.

DFSREvent

  • Checks for any errors with the Distributed File System Replication (DFSR).
  • Similar to the FrsEvent test. Same caveats apply.

SysVolCheck

  • Checks whether the SYSVOL share is ready.
  • In my experience this doesn’t test doesn’t seem to actually check whether the SYSVOL share is accessible. For example, consider the following:

    Notice SYSVOL exists. Now I delete it.

    But SysVolCheck will happy clear the DC as passing the test:

    So take these test results with a pinch of salt!

  • As an aside, in the case above the Netlogons test will flag the share as missing:
  • There is a registry key HKLM\System\CurrentControlSet\Services\Netlogon\Parameters\SysvolReady which has a value of 1 when SYSVOL is ready and a value of 0 when SYSVOL is not ready. Even if I turn this value to 0 – thus disabling SYSVOL, the SYSVOL and NETLOGON shares stop being shared – the SysvolCheck test still passes. NetLogons flags an error though.

Rest of the tests will be covered in a later post. Stay tuned!