Möchten Sie von einem Active Directory-Benutzer den Zeitpunkt der letzten Anmeldung auslesen, stellt sich die Frage, welches Attribut wir dafür brauchen: LastLogon oder LastLogonTimestamp.
Index
Unterschied zwischen LastLogon und LastLogonTimestamp
Erst einmal ist es wichtig, den Unterschied zwischen den Attributen zu kennen. Beide Attribute beinhalten den Zeitpunkt, an dem der Nutzer sich das letzte Mal angemeldet hat. Doch ist es nur das?
LastLogon gibt an, zu welchem Zeitpunkt sich ein Nutzer an einem bestimmten Domain Controller angemeldet hat.
LastLogonTimestamp gibt hingegen an, wann die letzte Anmeldung in der Domäne stattfand. LastLogonTimestamp wird auf alle Domain Controller im AD-Forest repliziert.
LastLogon hingegen wird nur auf dem bestimmten Domain Controller aktualisiert, auf dem die Anmeldung des Nutzers mit seinem Account stattgefunden hat. Hier findet keine Replikation auf die anderen Domain Controller statt. Das bedeutet, dass auf jedem Domain Controller das Attribut LastLogon für ein und denselben User-Account unterschiedlich ist.
Oder kurz:
Wir können zusammenfassend sagen, das LastLogonTimestamp die replizierte Version von LastLogon ist (unter Beachtung des Replikationszeitraumes). Falls sich ein Nutzer noch nie an einem Domain Controller angemeldet hat, ist der Wert der Attribute gleich Null.
Wichtig ist auch, dass die Replikation von LastLogonTimestamp nicht zeitnah erfolgt, sondern standardmäßig erst nach 14 Tagen (abzüglich eines zufälligen Wertes von 0 bis 5 Tage). Diese Einschränkung soll die die Netzwerkbandbreite, die durch die AD-Replikation belegt wird, so gering wie möglich halten.
Die Zeit, die die einzelnen Domain Controller verstreichen lassen, bevor der LastLogonTimestamp-Wert eines User-Objektes zu den anderen Domain Controllern repliziert wird, ist im Attribut msDS-LogonTimeSyncInterval festgelegt. Dieses findet man in den Eigenschaften des LDAP-Objektes der Domäne selbst und der Wert kann auch geändert werden. Ist der Wert nicht gesetzt, wird standardmäßig 9 bis 14 Tage festgelegt.
Die Values der Attribute LastLogon und LastLogonTimestamp sind im AD als numerische Werte (Large Integer) einer Länge von 8 Byte (64 Bit) hinterlegt.
Werte der Attribute mit PowerShell auslesen
Zunächst geht es darum, die Werte der Attribute LastLogon und LastLogonTimestamp für ein AD-Benutzerkonto auslesen zu können.
Bei LastLogonTimestamp funktioniert das ganz einfach über das Cmdlet „Get-ADUser“ (Import-Module ActiveDirectory), welcher die Identity (distinguishedName, objectGuid, objectSid oder samAccountName) entgegennimmt. Zudem wollen wir neben den Standard-Attributen auch das Attribut LastLogonTimestamp bei der Abfrage zurückerhalten:
$samAccountName = „maximilian.muster“
1 |
$user = Get-ADUser $samAccountName -Properties lastLogonTimestamp |
Werte in Datumsformat umwandeln
Um den Integerwert in ein lesbares Datum umzuwandeln, nutzen wir die Methode DateTime.FromFileTime(Int64), welche die Windows-Dateizeit in eine entsprechende Ortszeit konvertiert.
1 |
$lastLogonTimestamp = [datetime]::fromFileTime($user.lastLogonTimestamp) |
LastLogon: Verschiedene DCs abfragen
Um die letzte Anmeldung eines AD-Benutzer anhand des Attribute LastLogon herauszufinden, muss man sich die Werte aller Domain Controller heranziehen und das jüngste Datum auswählen. Wie schon erwähnt, sind auf jedem Domain Controller die Werte unterschiedlich, da keine Replikation für dieses Attribut stattfindet.
Zunächst suchen wir uns alle Namen der vorhandenen Domain Controller in der Domäne mit dem Cmdlet „Get-ADDomainController“:
1 |
$dcs = Get-ADDomainController -Filter * | Select-Object name |
Nach der Initialisierung der Variablen für den samAccountName des Nutzers
1 |
$samAccountName = "maximilian.muster" |
und der Zeit für LastLogon, welche uns den geringstmöglichen Wert zum Vergleich mit den anderen Datumswerten liefert,
1 |
$lastlogon=New-Object System.DateTime |
fragen wir von jedem Domain Controller das Attribut LastLogon ab und wandeln es in ein DateTime um:
1 2 3 4 5 6 7 8 9 |
foreach($dc in $dcs) { try { $user = Get-ADUser $samAccountName -Server $dc.name -Properties lastLogon $lastlogonToCheck = [datetime]::fromFileTime($user.lastlogon) } catch { continue } } |
LastLogon: Datumswerte verschiedener DCs vergleichen
Damit wir den aktuellsten Wert von LastLogon aus allen Domain Controllern erhalten, müssen wir die Datumswerte miteinander vergleichen. Sollte das in der Variable $lastLogonToCheck gespeicherte Datum älter sein als das aktuelle Datum aus $lastLogon, so wird dieses als neues LastLogon-Datum gesetzt, bis wir zum Schluss das höchste und aktuellste Datum erhalten haben:
1 2 3 4 5 6 7 8 9 10 11 12 |
foreach($dc in $dcs) { try { $user = Get-ADUser $samAccountName -Server $dc.name -Properties lastLogon $lastlogonToCheck = [datetime]::fromFileTime($user.lastlogon) if($lastlogon -lt $lastlogonToCheck) { $lastlogon = $lastlogonToCheck $lastLogonValue = $user.lastlogon } } catch { continue } } |
LastLogon und LastLogonTimeStamp formatieren
Zum Schluss lassen sich die Werte von LastLogon und LastLogonTimestamp noch formatieren. Sollte der Wert noch unserem Initialen Wert entsprechen, heißt das, dass sich der Nutzer noch nie angemeldet hat. Ansonsten lässt sich das Datum in ein beliebiges Format ändern:
1 2 3 4 5 6 7 8 9 10 11 12 |
if($lastlogon -ne (New-Object System.DateTime) -And $lastlogon -ne [datetime]::fromFileTime(0)) { $lastlogon = $lastlogon.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastlogon = "-" } if($lastLogonTimestamp -ne (New-Object System.DateTime) -And $lastLogonTimestamp -ne [datetime]::fromFileTime(0)) { $lastLogonTimestamp = $lastLogonTimestamp.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastLogonTimestamp = "-" } |
Hier nun noch einmal das komplette Skript und die Konsolenausgabe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
$dcs = Get-ADDomainController -Filter * | Select-Object name $samAccountName = "maximilian.muster" $lastlogon=New-Object System.DateTime foreach($dc in $dcs) { try { $user = Get-ADUser $samAccountName -Server $dc.name -Properties lastLogon $lastlogonToCheck = [datetime]::fromFileTime($user.lastlogon) if($lastlogon -lt $lastlogonToCheck) { $lastlogon = $lastlogonToCheck $lastLogonValue = $user.lastlogon } } catch { continue } } $user = Get-ADUser $samAccountName -Properties lastLogonTimestamp $lastLogonTimestamp = [datetime]::fromFileTime($user.lastLogonTimestamp) $lastLogonTimestampValue = $user.lastLogonTimestamp if($lastlogon -ne (New-Object System.DateTime) -And $lastlogon -ne [datetime]::fromFileTime(0)) { $lastlogon = $lastlogon.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastlogon = "-" } if($lastLogonTimestamp -ne (New-Object System.DateTime) -And $lastLogonTimestamp -ne [datetime]::fromFileTime(0)) { $lastLogonTimestamp = $lastLogonTimestamp.ToString("dd.MM.yyyy HH:mm:ss") } else { $lastLogonTimestamp = "-" } Write-Host("`nLastLogon: ") -ForegroundColor Yellow Write-Host("Wert: " + $lastlogonValue) Write-Host("Datum: " + $lastlogon) Write-Host("`nLastLogonTimestamp: ") -ForegroundColor Yellow Write-Host("Wert: " + $lastlogonTimestampValue) Write-Host("Datum: " + $lastLogonTimestamp) |
Nachdem wir nun die einzelnen Werte aus dem AD auslesen können, zeigt das nachfolgende Beispiel einen Praxis-Anwendungsfall für diese Thematik.
Beispiel-Abfrage: 90 Tage nicht angemeldet
Der Wert lastLogonTimestamp ist es eher dazu geeignet, inaktive Konten ausfindig zu machen, die sich schon lange Zeit nicht mehr in der Domäne angemeldet haben. Mit folgendem PowerShell-Skript lassen sich alle Nutzer ausfindig machen, welche sich die letzten 90 Tage nicht angemeldet haben:
1 2 |
$now = Get-Date $users = Get-ADUser -Filter * -Properties lastLogonTimestamp | Where {($now - [datetime]::FromFileTime($_.lastLogonTimestamp)).days -gt 90 } |
Das CmdLet Search-ADAccount bietet ebenfalls diese Möglichkeit:
1 2 3 |
$now = Get-Date $users = Search-ADAccount -AccountInactive -DateTime (($now).adddays(-90)) -UsersOnly |
Hier können ein oder mehrere Benutzer-, Computer- oder Dienstkonten abgerufen werden, die den in den Parametern angegebenen Kriterien entsprechen. Zu den Suchkriterien gehören der Konto- und Passwortstatus. Um die Suche auf Benutzerkonten zu beschränken, kann der Parameter UsersOnly angegeben werden. Der Suchparameter AccountInactive gibt an, dass dieses CmdLet nach Konten sucht, die sich in einem bestimmten Zeitraum oder seit einem bestimmten Zeitpunkt nicht angemeldet haben. Mit DateTime kann ein bestimmtes Datum bzw. eine bestimmte Uhrzeit angegeben werden.
Fazit
Das Auslesen des Zeitpunktes der letzten Anmeldung eines Benutzers ist nicht schwer. Sie müssen nur wissen, welches Attribut Sie am besten dafür verwenden. Wo sich LastLogon vs. LastLogonTimestamp unterscheiden, können Sie im ersten Abschnitt nocheinmal nachlesen
Wenn Sie die Attribute für die Benutzerverwaltung verwenden wollen, lässt sich dies bequem mit dem IDM-Portal umsetzen auf den Bearbeitungsseiten von Benutzern und Computern umsetzen. Hier kann ein entsprechendes Skript integriert werden, welches lastLogon bzw. lastLogonTimestamp ausliest und in ein lesbares Format umwandelt. So sehen Sie bequem das Datum der letzten Anmeldung in einer Oberfläche.
Weiterführende Artikel:
PowerShell: Aktive Computerobjekte mit LastLogonTimeStamp finden
Schnelle LDAP-Suche mit PowerShell – 3 Varianten
LastLogonTimeStamp vs. msDSLastSuccessfulInteractiveLogonTime
1 Comment
Leave your reply.