How to use a simple script to find the Schema version on all Domain Controllers in an Active Directory domain.
Before introducing a new operating system as a Domain Controller (DC) the current Active Directory Schema must be extended. Often the new server operating system adds new object classes and attribute types. The extension of the Schema is done with the adprep.exe tool and involves writing the changes to the DC holding the FSMO role Schema Master. Once the Schema Master is updated these extensions must be replicated to all other DCs in the forest.
The quickest way to determine to current Schema level is to use the DSQUERY tool.
Identify the distinguished name of the forest root domain, e.g., dc=example,dc=com.
Combine this with the string “cn=schema, cn=configuration“, e.g.:
“cn=schema, cn=configuration, dc=example, dc=com“
dsquery * "cn=schema,cn=configuration,dc=rn-test,dc=se" -scope base -attr objectVersion
The number corresponds to a certain Schema level:
13 | Windows 2000 |
30 | Windows Server 2003 |
31 | Windows Server 2003 R2 |
44 | Windows Server 2008 |
47 | Windows Server 2008 R2 |
56 | Windows Server 2012 |
69 | Windows Server 2012 R2 |
87 | Windows Server 2016 |
88 | Windows Server 2019 and 2022 |
It could be useful to the verify that the full replication actually has taken place. If the replication is for some reason either slow or even non-working this could cause serious problems later. To verify the Schema version on a single Domain Controller you could use ADSIEDIT.
Start the ADSIEDIT tool, select “Connect to….” and in the “Select a well known Naming Context” choose Schema.
Expand until you see the “CN=Schema, CN=Configuration..” and select Properties. Locate the objectVersion attribute and note the number.
This shows that in this case above the Schema version is windows 2008 R2 (version 47). However, this will only prove that this particular DC has this level and we still does not know the rest of the Domain Controllers. In large domains with, say 20+ DCs, it is quite difficult to attach to each DC with ADSIedit and do this manually.
We could instead use the old but useful dsquery tool and check the same attribute: (all in one line)
dsquery * cn=schema, cn=configuration, dc=exampledomain, dc=com -scope base -attr objectVersion -s DC-NAME
The line must be altered with the correct path to the actual domain and also be directed to each Domain Controller with the -s switch.
I wrote a short script that will automatically find all DCs and print the Schema version. This should make it easy to verify that all Domain Controllers are up to date and that the new Schema has been successfully replicated to every DC in the domain.
_________________________________________________________@ECHO OFF
REM Change the line below. Example: SET domain=dc=mydomain,dc=com
SET domain=dc=exampledomain,dc=com
ECHO.
ECHO Finding Schema Level on Domain Controllers in domain %domain%..
SET file=schemainput.txt
dsquery server -o rdn > %file%
FOR /f %%a IN (%file%) DO CALL :Loop %%a
REM Cleaning up the temporary file.
IF EXIST %file% DEL %file%
GOTO :eof
:Loop
SET dc=%1
ECHO.
ECHO %dc%
dsquery * cn=schema,cn=configuration,%domain% -scope base -attr objectversion -s %dc%|FIND /i /v “objectversion”
GOTO :eof
_________________________________________________________
Copy the script and make sure the line breaks are not lost. Save with .cmd extension in any folder and alter the “domain” variable inside the script to your specific domain name. The script makes no changes to any DC and is read-only. The script is classic CMD batch language and needs not Powershell installed and works on all Windows versions with the dsquery tool installed.
All Domain Controllers should display the same version, if not the replication issues must be investigated and solved.
Another very quick way to check this with only one command line is using the repadmin tool:
repadmin /showattr * “cn=schema,cn=configuration,dc=yourdomain,dc=com” /atts:ObjectVersion
However the output is a little bit more difficult to read and spot inconsistencies.
These instructions were PERFECT. Thank you so much.
Great script!! Found a lone entry for an RODC that was no longer in our domain but never cleared properly.
Nice….Thank you
worked perfect. Thanks