MSXFAQ MeetNow aktiv: Komm doch einfach dazu.

AD Change Detection

Im Active Directory ändert sich immer wieder etwas. Es muss nicht immer ein neuer Benutzer sein. Auch Gruppenmitgliedschaften, LastLogin-Feld, User-Zertifikate etc. bedeuten immer eine Veränderung. Gerade diese Änderungen sind für eine Automatisierung interessant, weil Sie darauf weitere Prozesse ableiten oder auch bösartige Veränderungen erkennen können. Wenn ein neues Objekt in die DomainAdministrator-Gruppe aufgenommen wird, ist dies durchaus eine Meldung wert.

Änderungen erkennen

Damit stellt sich die Frage, wie ich als Administrator oder Software solche Veränderungen erkennen kann. Kann mit das AD informieren oder muss ich regelmäßig nachfragen und in welcher Form bekomme ich die Änderungen. Auch die Frage der erforderlichen Berechtigungen, der Nutzbarkeit über mehrere Domains hinweg etc. sind zu berücksichtigen. Mir sind aktuelle drei genutzte Wege bekannt, von denen zwei auf LDAP-Felder aufsetzen.

Jedes AD-Objekte hat verschiedene Properties und zumindest "uSNChanged" und "whenChanged" sind Felder, die einfach abgefragt werden können:

  • USNLastChanged-Feld
    Jeder Domain Controller verwaltet seine eigene USN-Nummerierung und bei einer Änderung wird bei dem Objekte der Wert auf den aktuell höchsten Wert gesetzt. Das Feld selbst wird nicht zwischen DCs repliziert. Wenn ihre Abfrage also den DC wechseln möchte oder muss, muss er wieder am Anfang bei 0 anfangen, um nichts zu überlesen. Bei einem Polling sollte sich ihre Software also den letzten USN-Stand merken, um von da an wieder weiter zu suchen. Sie bekommen aber nur Änderungen auf Objekt-Level, die sich direkt ändern. Wenn Sie einen Benutzer in eine Gruppe aufnehmen, dann ändert sich das Feld "member" der Gruppe und damit auch nur die USB der Gruppe. Das Feld "memberOf" beim Benutzer wird "berechnet" und daher ändert sich beim Benutzer keine USN.
    Ein Beispiel finden sie auf Get-USNChanges
  • whenChanged-Feld
    Vielleicht ist daher das "whenChanged"-Attribute eine Alternative, welche auch pro DC gehalten wird. Sie könnten hier aber z.B. gezielt nach Objekten suchen, die sich in den letzten Minuten geändert haben. Im Grund gelten aber ansonsten die gleichen Einstellungen wie bei der USN.
    Ein Beispiel habe ich auf GET-ADChanges beschrieben.
  • Dirsync-API
    Diese API nutzen z.B. auch Domain Controller untereinander. Sie müssen dazu Domain-Admin sein oder zumindest das Recht "Replicating directory changes" haben. Dann bekommen Sie aber nicht nur geänderte Objekte, sondern sogar einzelne Felder. Das ist insbesondere bei Änderungen von Gruppenmitgliedschaften sehr hilfreich. Aber auch sonst sehen Sie genau, welches einzelne Feld geändert wurde. Sie können mit dem DirSync-Cookie auch einen anderen DC mit der gleichen Replikation der Partition ansprechen. Sie verpassen damit keine User aber eventuell werden ein paar früher geänderte Objekt erneut geliefert.
    Mehr Details finden Sie hierzu auf DirSync-API im Detail.

Bei allen drei Schnittstellen sehen Sie aber immer nur den letzten Stand. Wenn zwischen zwei Abfragen ein Feld oder Objekt mehrfach geändert wurde, ist es nur eine Änderung. Sie haben auch keinen Zugriff mehr auf die vorherige Information. Wer dies benötigt, muss sich einen Cache oder ein Replikat der erforderlichen Informationen vorhalten. Das macht z.B. ADSync / AADConnect mit seinem Metaverse.

Theoretisch könnten Sie über Debugging-Schnittstellen, Eventlog und Filter-DLLs sich tief in die Domain Controller einklinken und auch so Änderungen nicht nur erkennen sondern sogar blockieren. Es gibt tatsächlich solche Programme, die privilegierte Funktionen aus der Ferne verhindern. Das das ist dann nicht mal eben per PowerShell oder VBScript umgesetzt und ich vermute mal, dass kaum jemand meiner Leser eine DLL kompiliert, die im AD/LDAP/LSASS-Prozess eingebunden wird.

Vergleich

Aber auch mit drei Schnittstellen können wir die verschiedenen Aspekte noch einmal gegenüberstellen.

Kriterium uSNChanged whenChanged DirSyncAPI

API

LDAP

LDAP

LDAP

Berechtigungen

Leserechte auf das Objekt

Leserechte auf das Objekt

DirectoryReplication

Scope

Pro Domain/Partition
Pro OU
Pro Objekt
Pro Domain/Partition
Pro OU
Pro Objekt
Pro Domain/Partition
Pro OU (?)
Pro Objekt (?)

Forestweit

Ja, wenn GC gefragt und Object im GC

Ja, wenn GC gefragt und Object im GC

Nein

Push

Nein

Nein

Nein

Details

Objekt

Objekt

Feldinhalt
Teilfeld (Array)

Merker

LastUSN pro DC

whenChanged pro DC

DirSync Cookie pr DC

DC Wechsel

Neustart bei 0 erforderlich

Neustart der Abfrage erforderlich DC-Wechsel mit gleichem Replikat mit Einschränkungen möglich.

Aktionen

Add, Modify, Move

Add, Modify, Move

Add, Modify, Move, Delete

Server-Version

Eigentlich jeder LDAP-Server als auch OpenLDAP, Samba etc.

Eigentlich jeder LDAP-Server als auch OpenLDAP, Samba etc.

Windows Domain Controller

Die Überwachung auf Änderungen mit uSNChanged oder whenChanged unterscheidet sich quasi nur in dem Feld, auf dessen Inhalt wir filtern und das wir uns merken müssen, um bei einem folgenden Aufruf nur die danach veränderten Objekte zu erhalten.

Beide haben aber die Einschränkung, dass sie nur auf der Ebene des Objekts eine Änderung erkennen und keine Details zu den einzelnen Feldern bereitstellen. Zudem können Sie nicht erkennen, wenn ein Objekt gelöscht oder in eine andere nicht überwachte OU verschoben wurde. Es "verschwindet" einfach und wird nicht mehr gesehen. Daher gibt es durchaus einige Verzeichnistools, die immer mal wieder einen "FullScan" oder "FulSync" machen, um solche Unstimmigkeiten zu erkennen und zu korrigieren.

Deutlich leistungsfähiger ist hier die DirSyncAPI, die aber nicht jedem Anwender zur Verfügung steht. Es gibt eigenes ein Recht, welches Sie z.B. dem Dienstkonto zuweisen müssen, damit es dann über diesen Weg die Änderungen in deutlich feinerer Auflösung bekommt.

Notification/Webhook?

Über die MMC für AD Sites and Services als auch die Kommandozeile "RepAdmin.exe" können Sie eine Replikation beschleunigen. Das Verfahren wird oft als "Push" beschrieben aber es ist technisch ein Anstoßen eines Pull auf dem Ziel. Meines Wissens gibt es keine Möglichkeit, dass ein Domain Controller selbst aktiv wird und einen fremden Prozess über Änderungen informiert.

Im AzureAD bzw. Microsoft Graph gibt es solche Schnittstellen in Form von Webhooks. Die eigene Lösung stellt einen Webservice bereit und meldet diesen bei Entra ID an. Bei Änderungen sendet Entra ID dann einen "HTTP-POST" an den eigenen Server.

Diese Funktion gibt es nicht beim Windows Domain Controller

Die richtige API?

Solange sie noch einen lokalen Domain Controller haben, können Sie sehr einfach per PowerShell nicht nur alle Objekte aus dem Verzeichnis suchen und lesen, sondern auch gezielt nach Änderungen suchen und basierend darauf dann eigene Aktionen auslösen. Die Suche über USN dürfte in den meisten Fällen am einfachsten und schnellsten sein. Auch die Speicherung einer numerischen USN ist noch einfacher als ein Zeitstempel. In allen Fällen müssten Sie darauf achten, dass Sie sich auch den Domaincontroller merken, da sowohl USN, Datum und DirSync-Cookie auf den Server bezogen sind. Ihre Software sollte also immer damit umgehen können, die Änderungserkennung neu zu starten.

Weitere Links