如何批量统计AD账户最后一次登录时间

在许多IT企业由于管理不善,AD用户账号出现大量过期或不在使用中的账户,如何有效导出这些用户账户最后一次登录时间,经过IT部确认之后再删除这些用户,而不是直接删除XX天前未登录的用户(比如有些账户不一定需要登录,但却非常重要,比如一些邮箱账户或资源账户),微软提供了CSDEV工具,这个工具可以导出用户属性的Lastlogon,但是导出的结果有一个问题,是一串的数字,需要经过多次转换才能变成相应的日期和时间(转换方法可以参考:http://www.mcse.org.cn/showtopic-6953.html),有没有更好的办法,当然有,而且还不少,比较利用工具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也非常容易实现,在此不再强调。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值