利用脚本批量统计AD域用户最后一次登录时间

AD用户账号出现大量过期或不在使用中的账户,如何有效导出这些用户账户最后一次登录时间,经过IT部确认之后再删除这些用户,而不是直接删除XX天前未登录的用户(比如有些账户不一定需要登录,但却非常重要,比如一些邮箱账户或资源账户),微软提供了CSDEV工具,这个工具可以导出用户属性的Lastlogon,但是导出的结果有一个问题,是一串的数字,需要经过多次转换才能变成相应的日期和时间,有没有更好的办法,当然有,而且还不少,比较利用工具truelastlogon,reallastlogon,oldcmp,除此之外还有更好的方法就是VBS脚本,下面以一个叫lastlogon.vbs脚本为例,内容如下:

Option Explicit

Dim objRootDSE, strConfig, adoConnection, adoCommand, strQuery

Dim adoRecordset, objDC

Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()

Dim strDN, dtmDate, objDate, objList, strUser

Dim strBase, strFilter, strAttributes, lngHigh, lngLow

‘ Use a dictionary object to track latest lastLogon for each user.

Set objList = CreateObject(“Scripting.Dictionary”)

objList.CompareMode = vbTextCompare

‘ Obtain local Time Zone bias from machine registry.

‘ This bias changes with Daylight Savings Time.

Set objShell = CreateObject(“Wscript.Shell”)

lngBiasKey = objShell.RegRead(“HKLM\System\CurrentControlSet\Control\” _

& “TimeZoneInformation\ActiveTimeBias”)

If (UCase(TypeName(lngBiasKey)) = “LONG”) Then

lngBias = lngBiasKey

ElseIf (UCase(TypeName(lngBiasKey)) = “VARIANT()”) Then

lngBias = 0

For k = 0 To UBound(lngBiasKey)

lngBias = lngBias + (lngBiasKey(k) * 256^k)

Next

End If

‘ Determine configuration context and DNS domain from RootDSE object.

Set objRootDSE = GetObject(“LDAP://RootDSE”)

strConfig = objRootDSE.Get(“configurationNamingContext”)

strDNSDomain = objRootDSE.Get(“defaultNamingContext”)

‘ Use ADO to search Active Directory for ObjectClass nTDSDSA.

‘ This will identify all Domain Controllers.

Set adoCommand = CreateObject(“ADODB.Command”)

Set adoConnection = CreateObject(“ADODB.Connection”)

adoConnection.Provider = “ADsDSOObject”

adoConnection.Open “Active Directory Provider”

adoCommand.ActiveConnection = adoConnection

strBase = “<ldap: "="" &="" strconfig="">”

strFilter = “(objectClass=nTDSDSA)”

strAttributes = “AdsPath”

strQuery = strBase & “;” & strFilter & “;” & strAttributes & “;subtree”

adoCommand.CommandText = strQuery

adoCommand.Properties(“Page Size”) = 100

adoCommand.Properties(“Timeout”) = 60

adoCommand.Properties(“Cache Results”) = False

Set adoRecordset = adoCommand.Execute

‘ Enumerate parent objects of class nTDSDSA. Save Domain Controller

‘ AdsPaths in dynamic array arrstrDCs.

k = 0

Do Until adoRecordset.EOF

Set objDC = _

GetObject(GetObject(adoRecordset.Fields(“AdsPath”).Value).Parent)

ReDim Preserve arrstrDCs(k)

arrstrDCs(k) = objDC.DNSHostName

k = k + 1

adoRecordset.MoveNext

Loop

adoRecordset.Close

‘ Retrieve lastLogon attribute for each user on each Domain Controller.

For k = 0 To Ubound(arrstrDCs)

strBase = “<ldap: "="" &="" arrstrdcs(k)="" strdnsdomain="">”

strFilter = “(&(objectCategory=person)(objectClass=user))”

strAttributes = “distinguishedName,lastLogon”

strQuery = strBase & “;” & strFilter & “;” & strAttributes _

& “;subtree”

adoCommand.CommandText = strQuery

On Error Resume Next

Set adoRecordset = adoCommand.Execute

If (Err.Number <> 0) Then

On Error GoTo 0

Wscript.Echo “Domain Controller not available: ” & arrstrDCs(k)

Else

On Error GoTo 0

Do Until adoRecordset.EOF

strDN = adoRecordset.Fields(“distinguishedName”).Value

On Error Resume Next

Set objDate = adoRecordset.Fields(“lastLogon”).Value

If (Err.Number <> 0) Then

On Error GoTo 0

dtmDate = #1/1/1601#

Else

On Error GoTo 0

lngHigh = objDate.HighPart

lngLow = objDate.LowPart

If (lngLow < 0) Then

lngHigh = lngHigh + 1

End If

If (lngHigh = 0) And (lngLow = 0) Then

dtmDate = #1/1/1601#

Else

dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _

+ lngLow)/600000000 - lngBias)/1440

End If

End If

If (objList.Exists(strDN) = True) Then

If (dtmDate > objList(strDN)) Then

objList.Item(strDN) = dtmDate

End If

Else

objList.Add strDN, dtmDate

End If

adoRecordset.MoveNext

Loop

adoRecordset.Close

End If

Next

‘ Output latest lastLogon date for each user.

For Each strUser In objList.Keys

If (objList.Item(strUser) = #1/1/1601#) Then

Wscript.Echo strUser & “;Never”

Else

Wscript.Echo strUser & “;” & objList.Item(strUser)

End If

Next

‘ Clean up.

adoConnection.Close

这个脚本我们不要直接运行,否则我们只能看到屏幕多次弹出每个用户最后一次登录时间,我们把这个结果重定向到一个文件中去,执行下面步骤:

C:\>cscript lastlogon.vbs>lastlogon.csv

执行完毕生成一个CSV文件,打开此文件,可以看到最后1次登录时间,个人测试的结果文档内容如下:

从上图很容易看出最后一次登录时间,有些用户从来没有登录也会显示在上面。(如果想把最后一次登录时间作为独立一列分离出来,用Excel也非常容易实现,在此不再强调。)

posted @ 2012-12-17 11:19  kevin.gg  阅读(2318)  评论(0)    收藏  举报