如何知道域用户login的时间?

在Windows 2003域控制器上的“安全”事件日志中,我看到事件540的几个条目 – “成功的networkinglogin”在整个一天中相隔数分钟。

对特定用户来说,在特定的日子里,第一个这样的用户是否必须login到他们的机器?

如果没有(或者即使如此)有另一种(更好的)方法来告诉用户什么时候在早上login?

如果您正在寻找特定客户端计算机上的交互式login,则该客户端计算机上的事件就是您需要查看的地方。 例如,使用caching的凭据login的用户不会在域控制器的事件日志中创build条目。 即使您不想使用caching的凭据login,configuration客户端计算机以审计login事件并查看客户端计算机的事件日志,将会为您提供最好,最准确,最容易定位的信息。

如果您知道您的用户当前login的计算机,请尝试Sysinternals Suite中的psloggedon 。

AD用户对象上有一个名为Last-Logon-Timestamp的属性。 每次用户login时都会进行更新,但不会每14天更新一次,因为它将用于search无效帐户。 如果您愿意为域中的每个DC轮询此信息,则可以将其用作更精确的计数器。 从那里你可以build立一个用户身份validation的时间,而不仅仅是在早上。

从标题“如何知道域用户何时login”的第一个问题取决于用户login的平台。 对于Windows 2000 / XP / 2003,使用logintypes2的事件ID 528将显示来自本地或域帐户的交互式login。 LogParser是一个很好的工具来parsing来自大量机器的事件日志,并支持大量的输出。 因此,例如,您可以使用以下内容来查询远程计算机上的安全日志,并将其输出到选项卡分隔文件中:

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 

从Windows Vista / 2008/7上的安全日志中查询事件稍有不同,因为日志文件格式以及事件标识已更改。 与logintypes2的事件ID 4624将显示成功的交互式login。 我们可以使用wevtutil查询类似的数据并以XML格式输出:

 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 

至于看到事件ID 540出现在您的域控制器上的安全事件日志中:

事件540被logging有几个不同的原因。 因此,例如,当服务器服务访问共享资源时,您可以看到具有logintypes3的事件ID 540。 以下是Microsoft提供的此事件ID的logintypes:

2交互式用户在控制台上login到此计算机。

3networking从networkinglogin到此计算机的用户或计算机。

4批量批量服务器使用批量批量logintypes,其中进程可以代表用户运行,而无需用户直接干预。

5服务服务由服务控制pipe理器启动。

7解锁此工作站已解锁。

8 NetworkCleartext用户login到networking。 用户的密码以非哈希forms传递给authentication包。 内置身份validation在通过networking发送之前将所有哈希凭证打包。 证书不以明文(也称为明文)遍历networking。

9 NewCredentials调用者克隆其当前令牌并指定出站连接的新凭据。 新的login会话具有相同的本地身份,但对其他networking连接使用不同的凭据。

10 RemoteInteractive用户使用terminal服务或远程桌面连接远程login到此计算机。

11 CachedInteractive用户使用本地存储在计算机上的networking凭据login到此计算机。 没有联系域控制器来validation凭据。

快乐狩猎。

您可以在login脚本中创build一个将时间戳写入某个文件的行?

就像是?

净时间>> \服务器\ logonlogs \%用户名%.txt

道歉的长期职位,但这是我使用的。 你可以简化一下:

 ' ********************************************************************** ' 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

不涉及你的问题,但为什么不过滤掉这些事件,当你有这样的事件返回级别时,你不该该死的,3级或更高的严重错误的人,不要浪费你的时间!

如果您不想通过安全日志进行访问,则还可以尝试帐户locking和pipe理工具(链接) 。 这为ADUC中的帐户详细信息添加了一个额外的属性页,包括“上次login时间”。