An AD object isn’t just a name and some attributes — it’s the attributes plus a per-attribute change diary. That diary, called replication metadata, is what makes inter-DC replication, conflict resolution, and forensic auditing all work. In this Part 3 of the AD Replication Deep Dive series we trace exactly what changes inside that metadata when an object is created, replicated, modified, and replicated back.
Work through the four-step example below and the rest of the series falls into place.

uSNChanged and the per-attribute version + originating-DC stamps move.The four steps we’ll trace
- A user
jdoeis created on DC A. - That user replicates to DC B.
- The user’s password is changed on DC B.
- The password change replicates back to DC A.
At each step we’ll track two layers of metadata: object-level (uSNCreated, uSNChanged) and attribute-level (version, local USN, originating DSA, originating USN, timestamp). The attribute-level data lives inside a hidden attribute called replPropertyMetaData.
Step 1: jdoe is created on DC A
DC A’s next free USN is 1,000. The transaction commits and DC A’s USN advances to 1,001.
Object-level metadata:
uSNCreated = 1001— this object first appeared in DC A’s database at USN 1001.uSNChanged = 1001— latest change to the object on this DC.
Attribute-level metadata (one row per attribute that was set):
| Attribute | Version | Local USN | Originating DSA | Originating USN | Timestamp |
|---|---|---|---|---|---|
| displayName | 1 | 1001 | SiteA\DC-A | 1001 | 14:22:08 |
| sAMAccountName | 1 | 1001 | SiteA\DC-A | 1001 | 14:22:08 |
| userPrincipalName | 1 | 1001 | SiteA\DC-A | 1001 | 14:22:08 |
| pwdLastSet | 1 | 1001 | SiteA\DC-A | 1001 | 14:22:08 |
Read each attribute row as a sentence: “This value was set on DC-A in transaction 1001 at 14:22:08, and it’s the first version of this attribute.”
Step 2: jdoe replicates to DC B
DC B pulls from DC A and learns about the new object. DC B is at USN 2,499; the inbound transaction commits at USN 2,500.
Object-level metadata on DC B:
uSNCreated = 2500— from DC B’s perspective, the object first appeared here at 2500.uSNChanged = 2500.
Attribute-level metadata on DC B:
| Attribute | Version | Local USN | Originating DSA | Originating USN | Timestamp |
|---|---|---|---|---|---|
| displayName | 1 | 2500 | SiteA\DC-A | 1001 | 14:22:08 |
| sAMAccountName | 1 | 2500 | SiteA\DC-A | 1001 | 14:22:08 |
| userPrincipalName | 1 | 2500 | SiteA\DC-A | 1001 | 14:22:08 |
| pwdLastSet | 1 | 2500 | SiteA\DC-A | 1001 | 14:22:08 |
Notice the split: Local USN changed (it’s DC B’s number now) but Originating DSA, Originating USN, Version, and Timestamp are unchanged. That preserves the audit chain — DC B forever knows the original write came from DC A.
Step 3: Password change on DC B
A help-desk operator resets jdoe’s password. The session happens to land on DC B. DC B’s next USN is 3,777.
Critically — replication operates at the attribute level. Only pwdLastSet (and a couple of related credential attributes) gets a new row; the rest of the object is untouched.
Object-level metadata on DC B:
uSNCreated = 2500— never changes after creation.uSNChanged = 3777— the latest change to any attribute on this object.
Attribute-level metadata on DC B (only pwdLastSet updated):
| Attribute | Version | Local USN | Originating DSA | Originating USN | Timestamp |
|---|---|---|---|---|---|
| displayName | 1 | 2500 | SiteA\DC-A | 1001 | 14:22:08 |
| pwdLastSet | 2 | 3777 | SiteB\DC-B | 3777 | 09:14:55 next day |
Version goes 1 → 2 because pwdLastSet has been written for the second time. Originating DSA is now DC B because this write originated on DC B.
Step 4: Password change replicates back to DC A
DC A pulls from DC B. DC A only ships the one changed attribute — not the whole object — because the rest hasn’t changed. DC A’s USN advances to 1,333 with this inbound transaction.
Object-level metadata on DC A:
uSNCreated = 1001.uSNChanged = 1333.
Attribute-level metadata on DC A:
| Attribute | Version | Local USN | Originating DSA | Originating USN | Timestamp |
|---|---|---|---|---|---|
| displayName | 1 | 1001 | SiteA\DC-A | 1001 | 14:22:08 |
| pwdLastSet | 2 | 1333 | SiteB\DC-B | 3777 | 09:14:55 |
The forest now has a consistent forensic record: “pwdLastSet was changed once on DC-B at 09:14:55 (originating USN 3,777).” Every DC will agree on that story, no matter how the change reached them.
Why attribute-level replication matters
Older directory services replicated whole objects. Change one attribute → ship the entire 4KB user record over the wire. AD ships only the changed attribute (plus a row of metadata, <200 bytes). On a domain with millions of objects and thousands of daily changes, that’s a 20x bandwidth difference.
It also enables a critical conflict-resolution property: two DCs editing different attributes of the same object in parallel never conflict. Admin A changes telephoneNumber on DC1; admin B changes title on DC2 a second later. Both edits land, neither overwrites the other, because each attribute has its own metadata row.
Reading the metadata yourself
repadmin (built-in)
repadmin /showobjmeta DC01 "CN=jdoe,CN=Users,DC=contoso,DC=com"
Output: one row per attribute — Local USN, Originating DSA, Originating USN, Time/Date, Version, Attribute name.
PowerShell (richer object output)
Get-ADReplicationAttributeMetadata `
-Object "CN=jdoe,CN=Users,DC=contoso,DC=com" `
-Server DC01 |
Select-Object AttributeName, Version, LocalChangeUsn,
LastOriginatingChangeDirectoryServerIdentity,
LastOriginatingChangeUsn, LastOriginatingChangeTime |
Format-Table -AutoSize
This is the single most useful AD forensics command. “Who changed this user’s password and when?” — one query, deterministic answer.
Things that bite people
Confusing uSNChanged with last-modified-time
uSNChanged is a USN, not a timestamp. It bumps for any attribute write. To know when something happened, look inside replPropertyMetaData for the per-attribute timestamp.
Mistaking local USN for forensic evidence
Local USN tells you which transaction on this DC applied the change. It does not tell you who originated it. For that, read the Originating DSA and Originating USN columns. After a replication storm those numbers are your only clue to where a stray change actually came from.
Snapshots and version-number explosions
Reverting a DC VM bumps the invocation ID. That invalidates every other DC’s view of which originating USNs they’ve seen from that DC — the UTDV row is rebuilt from scratch. Innocuous if rare; a regular routine of snapshot-and-revert can shred replication health.
Auto-rotated linked attributes (group membership)
Group membership uses linked attributes, which have their own per-link metadata (msDS-ReplValueMetaData). repadmin /showobjmeta only shows attribute-level data; for membership forensics use Get-ADReplicationAttributeMetadata -ShowAllLinkedValues.
What’s next
You now know what changes inside an object during a replication cycle. Part 4 in the AD Replication Deep Dive pathway zooms out to the level above: how a complete naming context replicates between two DCs — the five-step request / send / process / confirm flow with HWMV and UTDV included in the payload.