Downloads related to this article:
The ADSI Schema Cache revealed
Like mentioned in the first article of this blog <Active Directory Service Interface (ADSI) and the Read Only Domain Controller (RODC) - Avoiding performance issues> ADSI utilizes a Schema Cache of the LDAP directories it has successfully contacted. In the article mentioned above you will also find an exemplary list of programmatic implementations that use ADSI.
Attributes that can be used on objects in a LDAP directory are defined in the schema of the LDAP directory, defining the syntax of the attribute, whether the attribute is multi-valued or not, whether the attribute is part of a linked attribute pair…
ADSI stores an excerpt of the LDAP schema in a text file containing the associations of:
- object classes ->
- class type
- superior class
- attributes (mustContain & mayContain)
ex: (1.2.840.1135184.108.40.206 NAME 'group' SUP top STRUCTURAL MUST (groupType ) MAY (member $ sAMAccountName $ …) )
- attributes ->
- whether the attribute is multi- or single-valued
ex: ( 1.2.840.1135220.127.116.11 NAME 'sAMAccountName' SYNTAX '18.104.22.168.4.1.1422.214.171.124.15' SINGLE-VALUE )
The path to the Schema Cache file on a Windows machine is (since Windows Vista):
The necessary information is downloaded from the Aggregate Schema which is stored in a subSchema object in the schema identified by the subschemaSubentry field, returned from a rootDSE call against a directory server.
The attributes of the subSchema entry containing the data the cache is built from are:
The Schema Cache gets downloaded from the directory when:
- we contact this directory for the first time
- the modifiedTimeStamp value on the Aggregate Schema is higher than the value we stored during the last download
(stored in HKCU\Software\Microsoft\ADs\Providers\LDAP\subschemaSubEntry -> Time)
Purposes of the Schema Cache are:
- performance improvement (we need not always ask the schema for the syntax of an attribute to display)
- the ease of use of the various ADSI Interfaces and their attributes
Up to here this sounds very cool. But (there’s always a but, isn’t it?) – let’s have a brief look on the conditions for downloading the Schema Cache.
We are totally fine with downloading the Schema Cache at the first contact to the directory. Checking the modifiedTimeStamp on the Aggregate Schema sounds fine as well - but it isn’t really.
Why (?) –> the Aggregate Schema modifiedTimeStamp should only change when we change something in the schema – and this shouldn’t happen to often in a lifetime of a directory.
Unfortunately this is not true – the subSchema entry is generated when the directory server loads the LDAP data base and the schema. This happens for example on every reboot of a directory server – saying every user who queries via ADSI against the rebooted directory server has to download the Schema Cache even though nothing has changed.
Imagine an environment with 100 000 users all over the world. All directory servers were rebooted during the weekend. Every user logs in on Monday morning and is downloading the schema cache because of the new modifiedTimeStamp value on the Aggregate Schema. In an environment with Exchange Schema extensions the size of the data would be around 4 MB -> 400 GB WAN traffic between the directory servers and the clients.
Something that shouldn’t happen for no necessary reason.
That’s why we are providing a fix in KB 2671874 that does the following:
- AD DS (directory service ) is starting
- AD database including schema gets loaded
- Aggregate Schema gets loaded
- modifiedTimeStamp of the Aggregate Schema gets overwritten with the modifiedTimeStamp of the Schema itself
=> the Aggregate Schema modifiedTimeStamp gets only updated when we modify the schema and we need not download the ADSI Schema Cache after every reboot of a domian controller.
Note: This functionality is already implemented in Domain Controllers with OS >= Windows Server 2012.
Now it sounds very cool. But again (there’s always a but, you remember?) – some admins (the clever ones) do backups of their ADs and their domain controllers – could come in quite handy in some cases, don’t you think?
Why is this a but (?) -> if you use any backup solution to perform a system state backup that utilizes the backup APIs of Windows on a domain controller the modifiedTimeStamp on each backed up naming context (like the schema) held by the domain controller get’s updated to the time of backup completion – by default.
So – if you perform a daily AD backup of your environment you will have every day a new modifiedTimeStamp value on the schema -> if we combine the above KB 2671874 with this behaviour we worsened the ADSI Schema Cache issue.
What should we do then – no domain controller reboots or no backups? None of the both – for obvious reasons.
Fortunately there is a mechanism to control this behavior – the DIT Database Partition Backup Signature (dSASignature) is used to monitor backups of each naming context. The data blob in dSASignature contains a Flags value which is set to 0x0 by default.
If we set the first bit of the Flags value to 1 (resulting in a 0x1 for a default dSASignature), the modifiedTimeStamp of the naming context get’s NOT updated on backup completion.
OK – finally it’s cool? Sort of, only a wee but – how do we edit the dSASignature – it’s not readable / editable with ADSI or any GUI known to me.
Downloadable sample code in C# and PoSh to perform this task – after performing that you’re done and really, finally it’s cool now – without any but:
To be honest about the PoSh - it's not really PoSh - it's embedded C# code in PoSh - but you need not compile it - so it's somehow still a PoSh script.
Additional info: we published a KB article covering this topic – < Heavy WAN and domain controller CPU usage when you perform system state backups >.
All the best
PFE | Have keyboard. Will travel.
- initially uploaded PoSh with typo - please use new version attached
- Added info about already builtin implementation of KB 2671874 to DCs with OS >= Windows Server 2012
- Corrected attribute names that are storing the Schema Cache relevant data
- added a further 'but' in a separate post <The ADSI Schema Cache revealed Part II>.