MSXFAQ MeetNow aktiv: Komm doch einfach dazu.

AD Schema Erweiterung

Das AD-Schema definiert, welche Objekte (Klassen) und welche Felder in der Datenbank definiert sind. Es ist kein Problem, das Schema um eigene Felder zu erweitern, wenn Sie dies mögen.

Klassen und Eigenschaften

In einem Active Directory gibt es Benutzer, Gruppen, Computer, OUs, Kontakte, InetOrgPerson und viele andere Objekte. Diese sind werden als "Klasse" beschrieben. Jedes dieser Objekte hat zugewiesene Eigenschaften. Einige werden durch das System verwaltet, z.B. USNChanged, USNCreated, WhenCrated, WhenChanged, ObjectGUID. Es gibt noch besondere Objekte, die einem besonderen Schutz unterliegen, z.B. das Kennwort oder auch die ObjectSID und SIDHistory. Das Active Directory legt beim DCPromo des ersten DCs eines Forest eine Basiskonfiguration an Klassen und Objekten an. Exchange und Skype for Business sind sicher die bekanntesten Produkte, die das Schema um eigene Felder und Klassen erweitern und bei denen auch ein Servicepack manchmal ein Schema Update erforderlich macht.

Das Schema ist für alle Domain in einem Forest nur einmal vorhanden und wird auf alle Domain Controller repliziert. Welche Klassen und Eigenschaften es gibt, können Sie sogar per MMC ansehen. Sie müssen nur die AD AdminTools installiert haben und eine DLL wie folgt registrieren.

regsvr32 schmmgmt.dll

Danach starten Sie einfach eine MMC.EXE und addieren das Snapin.

Sie sehen hier problemlos alle Klassen und deren Eigenschaften bzw. alle Eigenschaften

Sie können hier sogar einige Einstellungen ändern, wenn Sie die entsprechenden Berechtigungen haben, z.B. ob ein Objekt im GC ist. Das ist aber genau genommen keine Schema-Änderung, sondern nur eine Konfiguration. Aber auch eine Neuanlage von Attributen oder Klassen ist möglich.

Das geht einfach aber ist eine tiefgreifende Änderung. Lesen Sie daher erst einmal weiter.

Schema Administrator

Zur Erweiterung des Schema müssen Sie entsprechende Berechtigungen haben. Im Active Directory wird dies über die Mitgliedschaft in der Gruppe "Schema-Admin" gesteuert, die es nur genau einmal im Forest gibt.

Die Gruppe "Schema Administrators" sollte normalerweise leer sein!!

Sie müssen ihr Konto temporär erst in diese Gruppe aufnehmen und sich neu anmelden, ehe Sie das Schema ändern können.

Schema erweitern

In dem folgenden Beispiel möchte ich einfach meine Benutzer um ein weiteres Attribut erweitern. Firmen machen dies gerne, z.B.: zum eine Personalnummer zu speichern. Es gibt natürlich viele andere bestehende Felder, die sie dafür auch zweckentfremden könnten. Aber das lassen wir jetzt außen vor. Die Erweiterung erfordert mehrere Schritte:

Schritt Erledigt

OID besorgen

Jede Klasse und jede Eigenschaft hat eine weltweit eindeutige OID ( ähnlich zu SNMP-OIDs). Früher haben Entwickler, die eine Schema-Erweiterung benötigt haben, eine OID bereitgestellt. Mittlerweile beschreibt Microsoft einen Weg, eine Microsoft OID mit einer dynamisch erzeugen GUID zu kombinieren und damit ohne zentrale Prozesse eine eindeutige OID zu erhalten. Microsoft führt dazu folgende OID als Beispiel auf:

attributeID: 1.2.840.113556.1.8000.999999.1

Diese sollten Sie aber so nicht nutzen, denn ich bin sicher dass viele andere Entwickler genau diese Nummer einfach übernommen haben. Microsoft Exchange nutzt z.B. 1.2.840.113556.1.4.7000.102.1 für das Feld "msExchMailbox". Microsoft stell ein VBScript bereit, welches eine GUID "würfelt", diese dann in 7 Teile splittet und mit dem Prefix "oidPrefix = "1.2.840.113556.1.8000.2554" versieht. Ich habe das Skript in PowerShell gekürzt:

$guid = [guid]::NewGuid().ToString()
$oid = "1.2.840.113556.1.8000.2554" `
       + "." + [Convert]::ToInt64($guid.Substring(0, 4), 16) `
       + "." + [Convert]::ToInt64($guid.Substring(4, 4), 16) `
       + "." + [Convert]::ToInt64($guid.Substring(9, 4), 16) `
       + "." + [Convert]::ToInt64($guid.Substring(14, 4), 16) `
       + "." + [Convert]::ToInt64($guid.Substring(19, 4), 16) `
       + "." + [Convert]::ToInt64($guid.Substring(24, 6), 16) `
       + "." + [Convert]::ToInt64($guid.Substring(30, 6), 16) 
Write-Host "OID=$($oid)"

Das ist ihre neue "Basis-OID", an welche Sie dann z.B. aufsteigende Nummern pro Klasse und Attribut anhängen. Diese OID brauchen sie im Schritt "LDF-Datei erstellen".

 

Name festlegen

Geben Sie den Klassen und Attributen bitte "sinnvolle" Namen. Schauen Sie sich einfach die vorhanden Fehler an. Alles mit Exchange hat "msexch" als Prefix. Auch "msds", "msrtc", "msFRS" sind Beispiele. Ich nutze im Beispiel "msxfaq" als Prefix und sicher gibt es für ihre Firma oder ihr Produkt einen passenden Text.

Name: msxfaq-MitarbeiterID
 

LDF-Datei erstellen

Wenn Sie z.B. nur ein eigenes Attribut an z.B. an die Klasse "User" addieren wollen, dann geht das auch per MMC und sie können den Schritt überspringen. (Siehe weiter unten)

Wenn Sie nur genau ein Feld addieren wollen, könnten Sie eine Schema-Änderung sogar per MMC machen. Der klassische Weg ist aber eine LDF-Datei und LDIFDE. Hier ein Beispiel um zuerst ein neues Attribut anzulegen und diese dann an die Klasse User anzufügen.

Denken Sie daran, ihre eigene OID und DNs anzugeben 

dn: CN=msxfaq-MitarbeiterID,CN=Schema,CN=Configuration,DC=ROOTDN
objectClass: attributeSchema
attributeID: 1.2.840.113556.1.8000.2554.12759.49210.61396.20259.47236.3794204.253308.1
attributeSyntax: 2.5.5.12
isSingleValued: TRUE
lDAPDisplayName: msxfaq-MitarbeiterID
adminDisplayName: msxfaq-MitarbeiterID
adminDescription: Employee ID for msxfaq
oMSyntax: 64
searchFlags: 0
systemOnly: FALSE

dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-

Hinweis: Felder wie "dn", lDAPDisplayname etc. müssen natürlich eindeutig sein.

Eigentlich sollte es möglich sein, die Erweiterung um ein Attribut und die Änderung einer Klasse eine einer Datei zu kombinieren. Es gibt auch viele Beispieldateien von Microsoft, die genau das tun, z.B.

Allerdings ist mir das auf Windows 2025 nicht gelungen. Die identischen Zeilen in einer zweiten Datei haben hingegen problemlos funktioniert.

dn: CN=User,CN=Schema,CN=Configuration,DC=ROOTDN
changetype: ntdsSchemaModify
add: mayContain
mayContain: 1.2.840.113556.1.8000.2554.12759.49210.61396.20259.47236.3794204.253308.1
-

dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-

Beachten Sie, dass jeder Eintrag mit einem "dn" beginnt aber Änderungen mit einem "-" am Ende jeder Änderung abgeschlossen werden müssen. Auf ähnliche Weise können sie auch eigene Klassen definieren.

 

Gruppe SchemaAdministrators anpassen

Normalerweise ist die entsprechende Gruppe "leer" oder enthält nur den "Administrator" und sie müssen das Konto addieren, mit dem Sie die Schema-Erweiterung vornehmen wollen. Geänderte Gruppenmitgliedschaften werden immer erst nach einer neuen Anmeldung aktiv.

 

AD-Readyness

Sie sollten wie ein Schema ändern, wenn Sie andere Probleme in der AD-Replikation haben.

repadmin /replsum /bysrc /bydest /sort:delta

Hier sollten alle DCs als Fehler eine "0" haben. Danach können Sie sich zum Schema Admin machen und neu anmelden

 

LDF-Import oder MMC

Die eigentliche Erweiterung des Schemas erfolgt entweder mit der vorab generierten LDF-Datei und dem Programm LDIFDE oder einer MMC, in der sie das Schema-Snapin eingebunden haben.

Achtung: Das Schema kann immer nur erweitert aber nicht mehr geändert werden. Darauf weist die MMC auch beim addieren von neuen Attributen hin:

 

Für einen LDF-Import  nutze ich hier den Parameter "-c" um den SchemaNamingContext dynamisch einbinden zu lassen.

LDIFDE.EXE /i /f schema-msxfaq-mitarbeiterid-attr.ldf /v -c "CN=Schema,CN=Configuration,DC=rootdn" #schemanamingcontext
LDIFDE.EXE /i /f schema-msxfaq-mitarbeiterid-class.ldf /v -c "CN=Schema,CN=Configuration,DC=rootdn" #schemanamingcontext

Die Ausgabe sollte natürlich keine Fehler liefern. 

Bei der Erweiterung über die MMC müssen Sie im ersten Dialog den Feldnamen, die OID und den Typ angeben.

 

Danach können Sie das Attribut noch einmal öffnen und z.B. die Einstellungen zum GC oder der Indexierung anpassen. Dies sind genaugenommen keine Schemaänderungen von Feldern und deren Definition und können daher auch nachträglich geändert werden.

Beim Benutzer können Sie das neu angelegte Attribut dann einfach addieren.

 

Der Weg ist für einzelne Änderungen vermutlich einfacher als eine LDF-Datei,

 

Kontrolle

Eine Änderung des Schema muss auf alle DCs repliziert werden, Wenn Sie zugleich noch das neue Feld in den GC addieren, dann werden die DCs ihren Index und GC neu aufbauen, was eine kurze Lastspitze bedeuten kann. Insofern ist wieder ein Check der Replikation z.B. mit folgendem Befehl möglich.

repadmin /replsum /bysrc /bydest /sort:delta

Ein Blick ins Eventlog zeigt die entsprechenden Events:

 

Protokollname: Directory Service
Quelle:        Microsoft-Windows-ActiveDirectory_DomainService
Ereignis-ID:   1899
Aufgabenkategorie:DS-Schema
Ebene:         Informationen
Beschreibung:
Internal event: The following schema object was added. 
 
Schema object: 
CN=msxfaq-MitarbeiterID,CN=Schema,CN=Configuration,DC=forest3,DC=msxfaq,DC=de
Ereignis-XML:
Protokollname: Directory Service
Quelle:        Microsoft-Windows-ActiveDirectory_DomainService
Ereignis-ID:   1898
Aufgabenkategorie:DS-Schema
Ebene:         Informationen
Schlüsselwörter:Klassisch
Beschreibung:
Internal event: The following schema object was modified. 
 
Schema object: 
CN=User,CN=Schema,CN=Configuration,DC=forest3,DC=msxfaq,DC=de

Sie sehen, welcher Benutzer zu welchen Zeitpunkt welche Einträge geändert hat. Sie sehen aber nicht im Detail, was geändert wurde.

Natürlich können wir die neuen Attribute und Klassenänderungen auch in der MMC sehen:

 

 

Sie sehen, dass ich durchaus mehrere Versuche gebraucht habe. 

 

Gruppe "SchemaAdministrators" leeren

Vergessen Sie nicht als letzten Schritt die Gruppe der "Schema-Administratoren" wieder zu leeren. 

 

Schema exportieren, vergleichen, kopieren

So einfach, wie Sie mit LDIFDE das Schema erweitern können, ist auch ein Export möglich. In meinem Fall ist der Befehl:

ldifde -f Schema.ldf -d CN=Schema,CN=Configuration,DC=forest3,DC=msxfaq,DC=de

Die "Schema.ldf"-Datei enthält natürlich das gesamte Schema. Sie können damit z.B. einen Vergleich zwischen Forests durchführen.

dn: CN=msxfaq-MitarbeiterID,CN=Schema,CN=Configuration,DC=forest3,DC=msxfaq,DC=de
changetype: add
objectClass: top
objectClass: attributeSchema
cn: msxfaq-MitarbeiterID
distinguishedName: 
 CN=msxfaq-MitarbeiterID,CN=Schema,CN=Configuration,DC=forest3,DC=msxfaq,DC=de
instanceType: 4
whenCreated: 20250429224204.0Z
whenChanged: 20250429224204.0Z
uSNCreated: 12827
attributeID: 
 1.2.840.113556.1.8000.2554.12759.49210.61396.20259.47236.3794204.253308.1
attributeSyntax: 2.5.5.12
isSingleValued: TRUE
uSNChanged: 12827
showInAdvancedViewOnly: TRUE
adminDisplayName: msxfaq-MitarbeiterID
adminDescription: Employee ID for msxfaq
oMSyntax: 64
searchFlags: 0
lDAPDisplayName: msxfaq-MitarbeiterID
name: msxfaq-MitarbeiterID
objectGUID:: FZJgBUJUWkOmePWzMDzZCg==
schemaIDGUID:: RuLiBOdY3U68/y9NxsCZfg==
systemOnly: FALSE
objectCategory: 
 CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=forest3,DC=msxfaq,DC=de
dSCorePropagationData: 16010101000000.0Z
msDS-IntId: -1775885226

Sie sehen aber auch, dass diese Datei nicht wieder importiert werden kann. Das liegt nicht nur an den weiteren Feldern, die beim Import gar nicht akzeptiert werden, z.B. "dSCorePropagationData", "whenCreated", "whenChanged", "uSNChanged", "uSNCreated" und andere. Auch der Changetype "add" ist für ein Schema natürlich falsch.

Wenn Sie auf einem Server aber die ADAM-Rolle,  bzw. "AD LDS"-Rolle installieren, dann landen der "AD DS-/LDS-Schemaanalyzer" auf C:\Windows\ADAM\ADSchemaAnalyzer.exe". Damit können Sie das Schema von einem ADDS/ADLDS-Server oder einer LDIF-Datei einlesen, mit einem anderen Schema vergleichen und einzelne Felder markieren und als LDIF-Datei exportieren.

 

 

In meinem Fall war die Datei schon gut aber nicht perfekt.

dn: cn=msxfaq-MitarbeiterID,cn=Schema,cn=Configuration,dc=X
changetype: add
objectClass: attributeSchema
attributeId:
1.2.840.113556.1.8000.2554.12759.49210.61396.20259.47236.3794204.253308.1
ldapDisplayName: msxfaq-MitarbeiterID
attributeSyntax: 2.5.5.12
adminDescription: Employee ID for msxfaq
adminDisplayName: msxfaq-MitarbeiterID
# schemaIDGUID: 04e2e246-58e7-4edd-bcff-2f4dc6c0997e
schemaIDGUID:: RuLiBOdY3U68/y9NxsCZfg==
oMSyntax: 64
isSingleValued: TRUE
systemOnly: FALSE

Die Erweiterung der  "User"-Klasse wurde aber nicht mit exportiert. Ich habe auch nicht geprüft, ob der "Changetype" mit einem ADDS funktioniert. Dennoch ist dies natürlich eine gute Vorlage, die dann einfach angepasst werden kann.

Wenn ich mein produktives AD um eigene Felder erweitere, dann schau ich mir dennoch lieber meine LDF-Datei genau selbst an, importiere die erst in einem Labor um sie dann in der Produktion einzuspielen

Kein Undo aber Edit

Eine Schemaerweiterung ist nicht mehr rückgängig zu machen. Sie haben mit der Erweiterung ein neues Feld definiert und zu Klassen addiert. Damit konnten Sie später Objekte der entsprechenden Klasse anlegen und die Felder mit Inhalten versehen. Würden Sie nun das Feld aus dem Schema löschen, dann würden in der Datenbank noch Informationen in Feldern vorliegen, die keine Definition mehr haben. Nur theoretisch könnten die vorher natürlich alle Felder mit ihren Inhalten leeren und dann darauf hoffen, dass Sie das Feld im Schema entfernen können. Das ist aber nicht möglich.

Allerdings sind schon einige Modifikationen möglich

Sie können auf dem Attribut:

  • Attribute deaktivieren
    Sie können das Attribut als "deaktiviert" kennzeichnen. Es wird dann zwar nicht gelöscht und etwaige Klassen mit dem Feld und Inhalten bleiben auch erhalten, aber das Feld wird nicht mehr mit ausgeliefert und kann auch nicht mehr geschrieben werden. Es sieht so aus, als ob es einfach nicht mehr vorhanden ist.
  • Index, GC etc.
    Sie können auch jederzeit steuern, ob ein Attribut in den GC aufgenommen wird, indexiert wird oder beim Kopieren eines Benutzers über die MMC an die Kopie mit übertragen wird. Auch die Beschreibung ist noch nachträglich änderbar.

Sie können aber natürlich nicht die X.500-OID oder die Definition ändern. Bei der Klasse können Sie tatsächlich der Verknüpfungen zu optionalen Attributen auch noch im laufenden Betrieb ändern

 

Auch wenn wir eine einmal erfolgte Schemaerweiterung nicht mehr komplett rückgängig machen kann, so kann sie doch soweit deaktiviert werden, dass Sie nicht mehr stört und auch nicht mehr sichtbar ist. Ehe Sie aber ein Attribut sperren und die Verknüpfung mit einer Klasse lösen, sollten Sie alle Feldinhalte auf allen DCs vorab löschen, damit sie keinen Speicherplatz mehr benötigen und bei einer späteren Reaktivierung nicht zu unerwarteten Ergebnissen führen.

Testfälle

Diese Änderungsmöglichkeit hat mich natürlich neugierig gemacht und ich habe ein paar Testfälle durchgespielt. Ich habe dazu einen Single-DC.

Testfall  Ergebnis

Ich habe ein Attribut mit einen langen Wert gefüllt und dann die Maximallänge im Schema reduziert.

Ich konnte danach noch das Feld sehen und editieren aber beim Speichern hat das AD einen Fehler generiert. Ein Neustart des DC oder der jeweiligen MMC war nicht erforderlich.

Der "überlange Inhalt" des bereits früher befüllten Felds ist aber erhalten geblieben.

Also Entwickler sollten Sie also mit dem Fall umgehen können.

Attribute deaktivieren, obwohl es noch in einer Klasse referenziert ist 

Dies ist nicht möglich und wird von der MMC auch angezeigt:

Dann habe ich das Feld von der Klasse entfernt, obwohl noch eine Information drin steht.

Hier sind zwei Dinge suspekt:

  1. Ich kann das Feld weiterhin bei bestehenden Benutzern sehen und sogar editieren 
  2. Selbst neu angelegte Objekte vom Typ "User" haben das Feld

Ich habe dann den DC durchgestartet, um Caches etc. auszuschließen. Das Feld ist danach weiter sichtbar aber nicht mehr editierbar, obwohl ich Domain-Admin war.

 

Ein neu angelegter Benutzer hatte das Feld dann auch nicht mehr:

Das war ab er erst nach dem Neustart zu sehen.  Vermutlich müsste ich einfach länger auf einen internen Cleanup-Prozess warten.

Die Deaktivierungen kann ich natürlich auch immer wieder rückgängig machen.

Zusammenfassung

Früher waren eigene Schema-Erweiterungen immer so etwas wie die Königsdisziplin und zugleich Geheimwissenschaft. Schon die Frage der OID hat das Unterfangen sehr komplex aussehen lassen. Das ist es aber nicht, wenn man die Zusammenhänge kennt. Eine OID würfeln Sie sich über eine GUID und das von Microsoft vorgegebene Prefix einfach selbst zusammen und die LDF-Datei samt Import ist kein Hexenwerk. Natürlich müssen Sie vorab definieren, welche Attribute welchen Typ haben, wie diese benannt und später auch provisioniert werden. In der normalen MMC für Benutzer&Computer können diese nur über den Attribut-Editor eingesehen und manipuliert werden.

Dennoch würde ich heute das Risiko als gering einschätzen, dass Sie durch eine eigene Schema-Erweiterung ein höheres Risiko eingehen. Wenn Sie bei Benutzer, Computern oder anderen Objekten zusätzliche Informationen speichern oder sogar ganz neue Klassen für eigene Produkte und Lösungen anlegen wollen, dann ist ein gut geplantes eigenes Schema der richtige Weg. Es ist vor allem besser, als ein vorhandenes Feld zu kapern, welches gerade nicht genutzt wird. Besonders begeht sind hier ja die Exchange Custom Attributes 0-15 und Exchange Custom Extension Attribute 0-5, die von Exchange bereitgestellt und nicht genutzt werden aber dennoch ein Risiko sind. Andere Applikationen können diese auch nutzen und die "Disable-*" Commandlets leeren diese Felder. Siehe auch

Exchange Extension Attribute.

Wenn Sie Unterstützung bei diesen oder anderen Themen benötigen, dann können Sie gerne mich über die Firma Net at Work erreichen.
Net at Work und MSXFAQ

Weitere Links