Wie kann man feststellen, wann sich ein Domain-Benutzer angemeldet hat?


7

Im Ereignisprotokoll "Sicherheit" auf einem Windows 2003-Domänencontroller werden mehrere Einträge von Ereignis 540 - "Erfolgreiche Netzwerkanmeldung" angezeigt, die im Durchschnitt einige Minuten voneinander entfernt sind.

Ist die erste davon für einen bestimmten Benutzer an einem bestimmten Tag unbedingt die Zeit, zu der sich der Benutzer an seinem Computer angemeldet hat?

Wenn nicht (oder sogar wenn ja), gibt es eine andere (bessere?) Möglichkeit, um festzustellen, wann sich der Benutzer morgens angemeldet hat?

Antworten:


4

Wenn Sie auf einem bestimmten Client-Computer nach der interaktiven Anmeldung suchen, müssen Sie nach dem Ereignis suchen, das lange auf diesem Client-Computer liegt. Ein Benutzer, der sich beispielsweise mit zwischengespeicherten Anmeldeinformationen anmeldet, erstellt keine Einträge im Ereignisprotokoll eines Domänencontrollers. Selbst wenn Sie nicht nach Anmeldungen mit zwischengespeicherten Anmeldeinformationen suchen, erhalten Sie durch Konfigurieren der Clientcomputer zum Überwachen von Anmeldeereignissen und Durchsuchen des Ereignisprotokolls des Clientcomputers die besten, genauesten und am einfachsten zu lokalisierenden Informationen.


Ich stimme zu, meiner Meinung nach ist dies der beste / einfachste Weg, die Anmeldezeit eines Benutzers zu erfassen, ohne sie mit anderen irrelevanten Informationen zu verwechseln.
Greg Meehan

4

Wenn Sie wissen, auf welchem Computer Ihr Benutzer gerade angemeldet ist, versuchen Sie es mit psloggedon in der Sysinternals Suite.


Dies ist praktisch und geht schneller als das Durchsuchen der Ereignisprotokolle. Ich kann mir vorstellen, das ein bisschen zu benutzen. Aber es funktioniert nur für die aktuelle Sitzung ...
ℳ.

3

Für das AD User-Objekt gibt es ein Attribut namens Last-Logon-Timestamp. Es wird jedes Mal aktualisiert, wenn sich ein Benutzer anmeldet, wird jedoch nicht mehr als alle 14 Tage repliziert, da es zur Suche nach toten Konten verwendet werden soll. Es kann als genauerer Zähler verwendet werden, wenn Sie bereit sind, jeden Domänencontroller in der Domäne nach diesen Informationen abzufragen. Daraus können Sie einen Überblick darüber erstellen, wann sich Benutzer bei der Domain authentifiziert haben, wann immer dies geschieht, nicht nur am Morgen.


Dies ist nicht unbedingt die Zeit, in der der Benutzer <Strg> - <Alt> - <Del> gedrückt und sich an seinem Client-Computer angemeldet hat. Dies ist nur, wenn ihr Client-Computer mit einem DC sprach. Für einen kabelgebundenen Client auf einem Schreibtisch kann dies einer sein. Bei anderen Maschinen ist dies möglicherweise nicht der Fall.
Evan Anderson

2

Die erste Frage aus Ihrem Titel "Wie wird festgestellt, wann sich ein Domain-Benutzer angemeldet hat" hängt davon ab, auf welcher Plattform sich der Benutzer anmeldet. Für Windows 2000 / XP / 2003 zeigt die Ereignis-ID 528 mit Anmeldetyp 2 interaktive Anmeldungen von einem lokalen oder Domänenkonto an. LogParser ist ein großartiges Tool zum Parsen der Ereignisprotokolle von einer großen Anzahl von Computern und unterstützt eine große Anzahl von Ausgaben. So können Sie beispielsweise das Sicherheitsprotokoll auf einem Remotecomputer abfragen und in eine tabulatorgetrennte Datei ausgeben:

c:>logparser.exe "select TimeGenerated, SID from \\wksname\Security where EventID = 528" -i EVT -resolveSIDs:ON -q:ON -headers:off -o:TSV >> c:\UserLogons.txt

Das Abfragen von Ereignissen aus den Sicherheitsprotokollen unter Windows Vista / 2008/7 unterscheidet sich geringfügig darin, dass sich das Protokolldateiformat sowie die Ereignis-IDs geändert haben. Die Ereignis-ID 4624 mit Anmeldetyp 2 zeigt erfolgreiche interaktive Anmeldungen an. Wir können das wevtutil verwenden , um ähnliche Daten abzufragen und im XML-Format auszugeben:

c:>wevtutil qe Security /q:"*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task=12544 and (EventID=4624)] and EventData[Data[@Name='LogonType']='2']]" /e:Events > c:\UserLogons.xml

So wird die Ereignis-ID 540 in Ihren Sicherheitsereignisprotokollen auf Ihrem Domänencontroller angezeigt:

Ereignis 540 wird aus verschiedenen Gründen protokolliert. So könnte beispielsweise die Ereignis-ID 540 mit dem Anmeldetyp 3 angezeigt werden, wenn der Serverdienst auf eine gemeinsam genutzte Ressource zugreift. Hier sind die Anmeldetypen für diese von Microsoft bereitgestellte Ereignis-ID:

2 Interaktiv Ein Benutzer, der an der Konsole an diesem Computer angemeldet ist.

3 Netzwerk Ein Benutzer oder Computer, der vom Netzwerk an diesem Computer angemeldet ist.

4 Charge Batch-Anmeldetyp wird von Batch-Servern verwendet, auf denen Prozesse möglicherweise im Auftrag eines Benutzers ausgeführt werden, ohne dass der Benutzer direkt eingreift.

5 Service Ein Service wurde vom Service Control Manager gestartet.

7 Entsperren Diese Workstation wurde entsperrt.

8 NetworkCleartext Ein Benutzer, der in einem Netzwerk angemeldet ist. Das Kennwort des Benutzers wurde in unverfälschter Form an das Authentifizierungspaket übergeben. Die integrierten Authentifizierungspakete enthalten alle Hash-Anmeldeinformationen, bevor sie über das Netzwerk gesendet werden. Die Anmeldeinformationen durchlaufen das Netzwerk nicht im Klartext (auch als Klartext bezeichnet).

9 NewCredentials Ein Anrufer hat sein aktuelles Token geklont und neue Anmeldeinformationen für ausgehende Verbindungen angegeben. Die neue Anmeldesitzung hat dieselbe lokale Identität, verwendet jedoch andere Anmeldeinformationen für andere Netzwerkverbindungen.

10 RemoteInteractive Ein Benutzer, der sich über Terminaldienste oder eine Remotedesktopverbindung remote an diesem Computer angemeldet hat.

11 CachedInteractive Ein Benutzer, der an diesem Computer mit Netzwerkanmeldeinformationen angemeldet ist, die lokal auf dem Computer gespeichert wurden. Der Domänencontroller wurde nicht kontaktiert, um die Anmeldeinformationen zu überprüfen.

Fröhliches Jagen.


Hier ist ein Link zu den neuen Ereignis-IDs und deren Bedeutung in Windows Vista / 2008/7 support.microsoft.com/kb/947226
Shaun Hess

2

Sie könnten in einem Anmeldeskript eine Zeile erstellen, die irgendwo einen Zeitstempel in eine Datei schreibt?

Etwas wie?

Nettozeit >> \ server \ logonlogs \% username% .txt


Das ist eine großartige Idee, das werde ich heute machen!
SpaceManSpiff

Ich weiß nicht, das scheint mir irgendwie ... schmutzig zu sein.
ℳ.

Es ist, aber es funktioniert ganz gut. Manchmal sind Informationen so unzugänglich oder in einem solchen Format, dass es wirtschaftlicher ist, etwas anderes zu tun.
Wannen

2

Entschuldigung für den langen Beitrag, aber das ist, was ich benutze. Sie könnten dies wahrscheinlich ein wenig rationalisieren:

' **********************************************************************
' AuditUsers
' ==========
'
'  UserAccountControl
'  SCRIPT                         0x0001 1
'  ACCOUNTDISABLE                 0x0002 2
'  HOMEDIR_REQUIRED               0x0008 8
'  LOCKOUT                        0x0010 16
'  PASSWD_NOTREQD                 0x0020 32
'  PASSWD_CANT_CHANGE             0x0040 64
'  ENCRYPTED_TEXT_PWD_ALLOWED     0x0080 128
'  TEMP_DUPLICATE_ACCOUNT         0x0100 256
'  NORMAL_ACCOUNT                 0x0200 512
'  INTERDOMAIN_TRUST_ACCOUNT      0x0800 2048
'  WORKSTATION_TRUST_ACCOUNT      0x1000 4096
'  SERVER_TRUST_ACCOUNT           0x2000 8192
'  DONT_EXPIRE_PASSWORD           0x10000 65536
'  MNS_LOGON_ACCOUNT              0x20000 131072
'  SMARTCARD_REQUIRED             0x40000 262144
'  TRUSTED_FOR_DELEGATION         0x80000 524288
'  NOT_DELEGATED                  0x100000 1048576
'  USE_DES_KEY_ONLY               0x200000 2097152
'  DONT_REQ_PREAUTH               0x400000 4194304
'  PASSWORD_EXPIRED               0x800000 8388608
'  TRUSTED_TO_AUTH_FOR_DELEGATION 0x1000000 16777216
'
'  objUser.get("userAccountControl")
' **********************************************************************

option explicit

' *** Global constants

const HKEY_CLASSES_ROOT   = &H80000000
const HKEY_CURRENT_USER   = &H80000001
const HKEY_LOCAL_MACHINE  = &H80000002
const HKEY_USERS          = &H80000003
const HKEY_CURRENT_CONFIG = &H80000005

const REG_SZ        = 1
const REG_EXPAND_SZ = 2
const REG_BINARY    = 3
const REG_DWORD     = 4
const REG_MULTI_SZ  = 7

' *** User account status flags

const SCRIPT                         = &H0001
const ACCOUNTDISABLE                 = &H0002
const HOMEDIR_REQUIRED               = &H0008
const LOCKOUT                        = &H0010
const PASSWD_NOTREQD                 = &H0020
const PASSWD_CANT_CHANGE             = &H0040
const ENCRYPTED_TEXT_PWD_ALLOWED     = &H0080
const TEMP_DUPLICATE_ACCOUNT         = &H0100
const NORMAL_ACCOUNT                 = &H0200
const INTERDOMAIN_TRUST_ACCOUNT      = &H0800
const WORKSTATION_TRUST_ACCOUNT      = &H1000
const SERVER_TRUST_ACCOUNT           = &H2000
const DONT_EXPIRE_PASSWORD           = &H10000
const MNS_LOGON_ACCOUNT              = &H20000
const SMARTCARD_REQUIRED             = &H40000
const TRUSTED_FOR_DELEGATION         = &H80000
const NOT_DELEGATED                  = &H100000
const USE_DES_KEY_ONLY               = &H200000
const DONT_REQ_PREAUTH               = &H400000
const PASSWORD_EXPIRED               = &H800000
const TRUSTED_TO_AUTH_FOR_DELEGATION = &H1000000

dim wsh_shell, wsh_env, domain_name, server_name
dim initial_ou, computer, last_logon, i

dim users(4, 1000) ' 0 = username, 1 = display_name, 2 = is_disabled, 3 = lastlogon_date, 4 = group membership
dim num_users
const MAX_USERS = 1000

wscript.echo "Audit users started at " & formatdatetime(now(), 0)

' *** Get the domain name

set wsh_shell = Wscript.CreateObject("Wscript.Shell")
set wsh_env   = wsh_shell.Environment("PROCESS")
domain_name   = wsh_env("USERDNSDOMAIN")
server_name   = wsh_env("COMPUTERNAME")
set wsh_env = nothing
set wsh_shell = nothing

' *** Open the Computers container

domain_name = split(domain_name, ".")

initial_ou = "LDAP://DC=" & domain_name(0)
for i = 1 to ubound(domain_name)
  initial_ou = initial_ou & ",DC=" & domain_name(i)
next

wscript.echo "Checking domain " & initial_ou

' *** Find all users

set initial_ou = GetObject(initial_ou)

num_users = 0
FindAllUsers initial_ou

' *** Post the data

for i = 0 to num_users-1
  wscript.echo users(0, i) & "," & users(1, i) & "," & users(2, i) & "," & users(3, i) & "," & users(4, i)
next

' *** All done

wscript.echo "Audit users finished at " & formatdatetime(now(), 0)

set initial_ou = nothing

wscript.quit 0


' **********************************************************************
' FindAllUsers
' ------------
' **********************************************************************

sub FindAllUsers(fau_OU)

  dim ou_name, user, user_dn, display_name, lastlogon_date
  dim ldap_user, group_array, i

  ou_name = fau_OU.distinguishedName

' *** First list users in this OU

  for each user in fau_OU
    if lcase(user.class) = "user" then
      user_dn = "LDAP://CN=" & user.displayName & "," & ou_name

' *** Check we haven't found too many users

      if num_users >= MAX_USERS then
        wscript.echo "WARNING: exceeded maximum number of users - " & cstr(MAX_USERS)
        exit for
      end if

' *** New user

      users(0, num_users) = lcase(user.samAccountName)

' *** Get the display name; error trap this because it can fail

      users(1, num_users) = ""

      on error resume next
      err = 0
      display_name = user.get("displayName")
      if err = 0 then users(1, num_users) = display_name
      on error goto 0

' *** Get the enabled/disabled status

      users(2, num_users) = user.get("UserAccountControl") and ACCOUNTDISABLE

      if users(2, num_users) = 0 then
        users(2, num_users) = "0"
      else
        users(2, num_users) = "1"
      end if

' *** Get the last logon date; this may fail so trap errors

      lastlogon_date = 0

      on error resume next
      set lastlogon_date = user.get("lastLogon")
      if err = 0 then
        if not isempty(lastlogon_date) then
          lastlogon_date = LongTimeToDate(lastlogon_date)
          if lastlogon_date < 0 then lastlogon_date = 0
        end if
      end if
      on error goto 0

      users(3, num_users) = formatdatetime(lastlogon_date, 0)

' *** Get the group membership

      users(4, num_users) = ""

      on error resume next

      err = 0
      set ldap_user = GetObject(user_dn)
      if err = 0 then
        on error goto 0

        group_array = ldap_user.MemberOf

        if not isempty(group_array) then
          if TypeName(group_array) = "String" then
            users(4, num_users) = group_array
          else
            for i = lbound(group_array) to ubound(group_array)
              if users(4, num_users) <> "" then users(4, num_users) = users(4, num_users) & ";"
              users(4, num_users) = users(4, num_users) & TrimGroupName(group_array(i))
            next
          end if
        end if

        set ldap_user = nothing
      end if

      on error goto 0

' *** Finished with this user

      num_users = num_users + 1
    end if
  next

' *** Now recurse into subcontainers

  for each user in fau_OU
    if lcase(user.class) = "organizationalunit" or lcase(user.class) = "container" then
      FindAllUsers user
    end if
  next

' *** All done

end sub


' **********************************************************************
' TrimGroupName
' -------------
' Turn the distinguished name into a simply group name
' **********************************************************************

function TrimGroupName(tgn_FullName)

  dim group_name, len_group, c

  TrimGroupName = ""
  group_name = ""

  len_group = len(tgn_FullName)
  if len_group < 4 then exit function

  for i = 4 to len_group
    c = mid(tgn_FullName, i, 1)
    if c = "," then exit for
    group_name = group_name + c
  next

  group_name = lcase(group_name)
  TrimGroupName = group_name

end function


' **********************************************************************
' LongTimeToDate
' --------------
' Convert the ADSI longint timestamp to a VBScript format date
' **********************************************************************

function LongTimeToDate(lt_Time)

  dim ltdate

  ltdate = lt_Time.HighPart * (2^32) + lt_Time.LowPart
  ltdate = ltdate / (60 * 10000000)
  ltdate = ltdate / 1440
  ltdate = ltdate + #1/1/1601#

  LongTimeToDate = ltdate

end function

JR


1

Nicht im Zusammenhang mit Ihrer Frage, aber warum nicht diese Ereignisse herausfiltern? Sie sollten sich nicht darum kümmern, wenn Sie diese Ereignisrückgabe haben. Fehler mit einem Schweregrad von 3 oder höher, verschwenden Sie keine Zeit!


Das Sicherheitsprotokoll "Erfolgsprüfung" und "Fehlerprüfung" enthält nur zwei Ebenen. Viele Sicherheitszertifizierungen erfordern auch, dass Sie diese Art von Ereignissen prüfen (wir müssen dies für PCI sowie für individuelle Clientanforderungen tun) - ich habe sie aktiviert und den Sicherheitsmitarbeiter sie herausfinden lassen. Außerdem möchte ich hinzufügen, dass Sie aus den sev2-Ereignissen, die den sev3-Ereignissen vorausgehen, eine Menge guter Diagnoseinformationen erhalten können.
Zypher

1

Wenn Sie nicht durch Ihre Sicherheitsprotokolle blättern müssen, können Sie auch die Tools zur Kontosperrung und -verwaltung (Link) ausprobieren . Dadurch wird den Kontodetails in ADUC eine zusätzliche Eigenschaftsseite hinzugefügt, einschließlich der "letzten Anmeldezeit".

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.