How to Configure Windows Server 2019 Active Directory Schema

The Active Directory schema defines all object classes and attributes that can exist in the directory. It is the blueprint that governs what data Active Directory stores about every object — users, computers, groups, and any custom object types. The schema is stored in a dedicated partition (the Schema NC) and replicated to every domain controller in the forest. Modifying the schema is irreversible and affects the entire forest, so planning and testing are critical. This guide covers schema viewing, extending the schema, and managing schema changes on Windows Server 2019.

Understanding the Schema Master Role

Schema modifications can only be made on the Schema Master, one of the five FSMO (Flexible Single Master Operation) role holders. Only one Schema Master exists per forest. Identify the current Schema Master:

Get-ADForest | Select SchemaMaster

Or using netdom or dsquery:

netdom query FSMO
dsquery server -hasfsmo schema

Installing the Active Directory Schema Snap-In

The Active Directory Schema MMC snap-in is not installed by default. Register the schema DLL and then add the snap-in to MMC. First, register the DLL:

regsvr32.exe schmmgmt.dll

Open MMC and add the Active Directory Schema snap-in:

mmc.exe
# File > Add/Remove Snap-in > Active Directory Schema > Add > OK

Alternatively, install the RSAT tools which include the schema management tools:

Add-WindowsCapability -Name "Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" -Online
Install-WindowsFeature RSAT-ADDS-Tools -IncludeAllSubFeature

Viewing Schema Objects with PowerShell

Use the ActiveDirectory module to explore the schema programmatically. List all attribute definitions in the schema:

Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext `
    -LDAPFilter "(objectClass=attributeSchema)" `
    -Properties lDAPDisplayName, attributeSyntax, isSingleValued |
    Select lDAPDisplayName, attributeSyntax, isSingleValued |
    Sort lDAPDisplayName

Find a specific attribute definition:

Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext `
    -LDAPFilter "(&(objectClass=attributeSchema)(lDAPDisplayName=department))" `
    -Properties * |
    Format-List lDAPDisplayName, attributeID, attributeSyntax, isSingleValued, rangeLower, rangeUpper

List all class definitions:

Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext `
    -LDAPFilter "(objectClass=classSchema)" `
    -Properties lDAPDisplayName, defaultObjectCategory |
    Select lDAPDisplayName |
    Sort lDAPDisplayName

Checking Schema Version

The schema version number indicates which Active Directory version extended the schema last. Higher values indicate newer extensions. Check the current schema version:

Get-ADObject -Identity (Get-ADRootDSE).schemaNamingContext -Properties objectVersion |
    Select objectVersion

Windows Server 2019 schema corresponds to objectVersion 88. Windows Server 2016 is 87, 2012 R2 is 69. If you have upgraded domain controllers but not extended the schema, run:

adprep.exe /forestprep
adprep.exe /domainprep

Enabling Schema Modifications

By default, schema modifications are disabled. Enable schema writes on the Schema Master before making changes:

Set-ADObject -Identity (Get-ADRootDSE).schemaNamingContext `
    -Add @{schemaUpgradeInProgress = 1}

# Or via registry on the Schema Master:
$registryPath = "HKLM:SYSTEMCurrentControlSetServicesNTDSParameters"
Set-ItemProperty -Path $registryPath -Name "Schema Update Allowed" -Value 1

Adding a Custom Attribute to the Schema

Extending the schema with a new custom attribute requires generating a unique OID. Use the Microsoft OID generation script or request an OID from IANA. For testing, use the Microsoft-allocated base OID range. Create an LDIF file for the new attribute:

dn: CN=ContosoEmployeeID,CN=Schema,CN=Configuration,DC=contoso,DC=local
changetype: add
objectClass: attributeSchema
cn: ContosoEmployeeID
attributeID: 1.2.840.113556.1.8000.2554.35423.35823.36312.100.1
lDAPDisplayName: contosoEmployeeID
adminDisplayName: Contoso Employee ID
adminDescription: Custom employee identifier for Contoso HR integration
attributeSyntax: 2.5.5.12
oMSyntax: 64
isSingleValued: TRUE
searchFlags: 1
schemaIDGUID:: 

Import the LDIF file using ldifde on the Schema Master:

ldifde -i -f C:SchemaChangesadd-contosoEmployeeID.ldf `
    -s schemamaster.contoso.local `
    -c "DC=X" "DC=contoso,DC=local" `
    -j C:SchemaChangeslogs

Adding the Custom Attribute to a Class

After creating the attribute, add it to an object class (e.g., the User class) so it appears on user objects. Create an LDIF modification file:

dn: CN=User,CN=Schema,CN=Configuration,DC=contoso,DC=local
changetype: modify
add: mayContain
mayContain: contosoEmployeeID
-

Import the class modification:

ldifde -i -f C:SchemaChangesadd-attr-to-user.ldf `
    -s schemamaster.contoso.local `
    -c "DC=X" "DC=contoso,DC=local"

Reloading the Schema

After schema changes, force a schema reload on the Schema Master without a reboot:

$rootDse = [ADSI]"LDAP://RootDSE"
$rootDse.Put("schemaUpdateNow", 1)
$rootDse.SetInfo()

Disable schema modifications after completing changes:

$registryPath = "HKLM:SYSTEMCurrentControlSetServicesNTDSParameters"
Set-ItemProperty -Path $registryPath -Name "Schema Update Allowed" -Value 0

Schema management in Windows Server 2019 Active Directory requires careful planning, a clear change management process, and thorough testing in a non-production lab environment before applying to production. Remember that schema changes replicate to every DC in the forest and most additions cannot be undone — attributes can be deactivated but not deleted. Always document every custom attribute and class change with its OID, purpose, and deployment date.