GET-USNChanges

Get-USNChanges ist der kleine Partner von GET-ADChanges und ermittelt geänderte Objekte anhand der USN, also der "unique Sequence Number", die im Active Directory pro Domaincontroller verwaltet und mit jeder Änderung hochgezählt wird. Im Gegensatz zu GET-ADChanges kann daher Get-USNChanges nur erkennen, dass sich ein Objekt verändert hat, aber nicht welche Feld betroffen war. Es ist also etwas allgemeiner.

Hintergrundwissen

Durch den Verzicht auf die Dirsync-API reichen aber z.B. "Lese-Rechte" aus das Active Directory und die relevanten Objekte. Das Recht hat eigentlich jeder Domänenbenutzer. Das gleiche Verfahren zur Erkennen von Änderungen nutzt z.B. auch der Exchange 2000/2003 RUS oder der Active Directory Connector, um Änderungen an Objekten zu erkennen und zu verarbeiten. Auch der Lync "User Replicator", verschiedene Spamfilter und Faxserver nutzen die USNs, um Änderungen an der Quelle nach zu verfolgen. Besondere Rücksicht muss man aber beim Löschen von Objekten an den Tag legen. Diese "erkennt" man nur, wenn Sie noch innerhalb der Tombstone-Zeit ab und an auch die gelöschten Objekte getrennt abfragen. Da USNs pro DC gültig sind, müssen Sie auch immer den gleichen DC als Quelle nutzen. Ist der DC down, dann sollten Sie warten. Bei einem Wechsel auf einen anderen DC sollten Sie bei USBN=0 wieder starten.

Funktion und Einsatz

Trotzdem ist "Get-USNChanges" kein Skript zweiter Wahl. Es ist durchaus interessant für den Einsatz in automatischen Prozessen und zur Fehlersuche. Es ermittelt die geänderten Objekte und sendet diese über die Pipeline nach nachfolgende Prozesse. Beispielhafte Anwendungen sind z.B. Exports von Einstellungen nach einer Änderung. Wer z.B. Gruppen anlegt oder ändert kann dies über die USN-Änderung erkennen und entsprechend ausgeben. Wer sich daher vorher das fragliche Objekt gespeichert hat, kann sogar die Werte vergleichen. Wer z.B. Änderungen an kritischen Gruppen (z.B. Domänen Administratoren) nachverfolgen will, ist mit Get-USNChanges schon sehr gut unterwegs. Er muss quasi nur noch ein paar Zeilen addieren und das Skript über den Taskplaner regelmäßig starten. Doch dazu später mehr.

Aufruf

Das Skript selbst benötigt keine weiteren Eingaben oder Voraussetzungen und einfach nur eine Powershell auf einem PC, welcher Mitglied eines Active Directory ist. Im Gegensatz zu GET-ADChanges sind auch keine privilegierte Berechtigungen erforderlich Beispielhafte Aufrufe sind:

# Aufruf ohne Paramter überwacht Default Domain alle 3 Sekunden mit Ausgabe auf Bildschirm und CSV
get-usnchanges.ps1

# Überwachung der Konfigurationpartition in eigenes Log
get-usnchanges.ps1 -basedn "cn=configuration,dc=msxfaq,dc=local" -csvfilename ".\config.csv"

# Sinnloser Aufruf. Once ohne LastUSN als Default startet und beendet sich
get-usnchanges.ps1 -once

Alle Änderungen werden so erst mal auf den Bildschirm geschrieben:

Die meisten Leser werden Get-USNChanges als Diagnosewerkzeug einsetzen und daher das CSV-Protokoll und die Bildschirmausgabe nutzen. Sie können das Skript aber auch auf zwei Arten leistungsfähiger nutzen:

Die Parameterdefaults sind so gewählt, dass Get-USNChanges einfach nur die aktuelle Anmeldedomäne überwacht und alle Änderungen seit dem Start des Programms auf den Bildschirm ausgegeben werden. Frühere Änderungen werden übersprungen.

Parameter

Die verschiedenen Optionen des Aufrufs von Get-USNChanges werden deutlich, wenn Sie sich die Parameter und deren Funktion anschauen. Die Parameter bedeuten im Einzelnen:

Typ Parameter Default Bedeutung
[string] $lastusn "-1" USN, bei der angefangen werden soll zu suchen. Ein Wert von -1 ignoriert alle bisherigen Änderungen und fängt nach der letzten Änderung an.
Ein Wert von 0 liefert alle Änderungen in der chronologischen Reihenfolge
[string] $domaincontroller localhost Name des DCs, welcher genutzt wird. Es muss sich aktuell dabei auch um einen GC handeln und wenn Sie mit LastUSN arbeiten, muss es immer der gleiche DC sein.
[string] $ldappath GC://localhost Optionaler LDAP-Pfad. Wenn, dann bitte komplett mit DC angeben, z.B.:
"LDAP://dname/dc=domain,dc=tld"
"GC://dcname"
[string] $usnfilename $null Dateipfad und Name zum Abspeichern und laden der USN, z.B. wenn mit "-once" das Skript immer nur einmalig gestartet wird oder auch nach einem Reboot des PCs wieder an der alten Stelle aufgesetzt werden soll.
[string] $csvfilename $null Optionale Angabe einer CSV-Datei, in welcher die geänderten Objekte protokolliert werden.
[int] $sleeptime 3 Sek Immer wenn das Skript eine Suche abgeschlossen und die Elemente ausgegeben hat, legt es eine "Pause" ein. Kürzere Pausen belasten das System mehr aber sie können schneller reagieren. Bedenken Sie aber, dass auch die DCs sich untereinander nicht "realtime" abgleichen.
[switch] $once $false Wird der Schalter "-once" gesetzt, dann beendet sich das Skript nach einem Durchlauf. Beachten Sie, dass dies nur in Verbindung mit einem Cookie-File Sinn macht. Ansonsten gibt es keine Änderungen zu melden
[switch] $noscreen $false Deaktiviert die zusätzliche Ausgabe auf den Bildschirm der gefundenen Änderungen. Sinnvoll, wenn die normale Ausgabe in die Pipeline nicht mit "| out-null" unterdrückt oder mit einem anderen Prozess weiter verarbeitet wird.
[switch] $verbose $false Durch die Angabe von "-verbose" werden detailliertere Ausgaben während der Verarbeitung gemacht, die bei eier Fehlersuche helfen können.

Da Powershell-Skripte nicht wirklich "verschlüsselt" sind, können Sie entsprechende Änderungen leicht selbst vornehmen.

Ausgaben

Die Bildschirmausgaben sind natürlich nur eine Funktion der Powershell, welche die Pipeline am Ende auf die Konsole schreibt. Eine Weiterverarbeitung ist natürlich sehr einfach möglich.

... in die Pipeline

Das Übergebene Objekte hat folgende Eigenschaften

Property Typ Beispiel Bedeutung
Timestamp DateTime Donnerstag, 16. Juni 2011 05:45:34 Zeitstempel, wann die Aktion erkannt wurde. Dies ist nicht identisch mit dem Zeitpunkt der Änderung. Diese kann auf einem anderen DC schon früher erfolgt sein und durch AD-Replikation verzögert sein.
usn String 32122412 Die aktuelle "USNChanged" des Objekts
class string User Objektklasse des geänderten Objekts
lastmodified DateTIME Donnerstag, 16. Juni 2011 05:43:34 Aktueller Inhalt von "LastModified" des Objekts. Beschreibt aber nur die Änderung des Objekts auf diesem DC.
dn String cn=user1 DistinguishedName des Objekts

Die Ausgaben sind "Objekte", d.h. per Pipeline können Sie die Ausgaben auch weiter verarbeiten. Das einfachste ist natürlich die Ausgabe in einer CSV-Datei

get-usnchanges.ps1 | export-csv .\aenderungen.csv

... CSV-Datei

Get-USNChanges schreibt aber zusätzlich die Änderungen auch in eine Datei ".changes.csv", sofern diese angegeben wird. Der Inhalt entspricht der Ausgabe in die Pipeline. Der Inhalt einer solchen Datei ist entsprechend überschaubar:

Diese Datei ist aber wirklich eher wie ein IISLog als Protokoll zu sehen und kann natürlich mit einer Volltextsuche o.ä. bearbeitet werden. Für eine zeitnahe Ausführung von Aktionen sollte jedoch besser die Pipeline-Ausgabe ausgewertet werden. Aufgrund der begrenzen Ausgabemöglichkeiten enthält die Spalte "Value" nur als Text darstellbaren Daten, d.h. String, numerische Werte. Arrays und andere komplexe Konstruktionen werden nicht ausgegeben.

Erweiterte Nutzung

Interessant wird der Einsatz natürlich, wenn man die letzte USN mit angibt oder die Funktion nutzt, die USN speichern zu lassen und dann immer wieder dort aufsetzt. Das funktioniert sehr gut für "AdHoc-Skripte", die über die Pipeline arbeiten.

Ein alternativer Weg ist, dass Sie das Skript aus ihrem Skript aufrufen und selbst anhand der durch die Pipeline erhaltenen Objekte die höchste USN ermitteln und sich selbst wegspeichern. Wenn Sie dann das Skript regelmäßig mit "once" aufrufen und die vormals letzte erhaltene USN wieder als Parameter angeben, haben Sie die volle Kontrolle.

Get-USNChanges ist "ReadOnly", d.h. es reichen "Lese-Rechte" als Domänenbenutzer aus. Erst wenn Sie die Ergebnisse natürlich nutzen, um ihrerseits Aktionen anzustoßen, muss das Skript entsprechende Berechtigungen vorweisen.

Einschränkungen

Zudem gibt es die Einschränkungen, dass z.B. nur direkte Änderungen erkannt werden. Wir ein Benutzer also in eine Gruppe aufgenommen, dann wird nur eine Änderung von "Member" an der Gruppe erkannt. Beim Benutzer ändert sich das Feld "MemberOf" nicht. Eine Aufzählung aller Besonderheiten würde aber den Rahmen dieses Artikels sprengen.

Download

Das Skript nutzt nur die in Powershell 2.0 vorhandenen Bordmittel. Wenn Sie aber als Weiterverarbeitung zusätzliche Befehle ausführen wollen, dann müssen Sie eventuell die erforderlichen Snapins erst nachladen

tools/get-usnchanges.1.0.ps1

Das Skript arbeitet von Hause aus "ReadOnly"

Weitere Links

Keywords:Powershell Dirsync LDAP Monitor