AD Accounts - Last Logon Timestamp

Anyone know what I'm doing wrong? I want to export the user accounts and last logon to an excel spreadsheet ... out of Active Directory ... below is a modified version of my script.


'**  Created by Brian Nettles for User Last Login for                                              **
'**  This script exports the following fields:                                                                                       **
'**  Username, Display Name, Last Login                                                                                          **
'**  Each line is tab delimited to be used for the XLS format                                                               **

'Global variables
Dim oContainer
Dim OutPutFile
Dim FileSystem

'Initialize global variables
Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")
Set OutPutFile = FileSystem.CreateTextFile("LastLogin_CORP.xls", True)

OutPutFile.WriteLine     "Username" & vbtab & "Display Name" & vbtab & "Last Logon Timestamp"

Set oContainer = GetObject("LDAP://OU=Accounts,DC=Corp,DC=Contoso,DC=com")

'Enumerate Container
EnumerateUsers oContainer

'Clean up
Set FileSystem = Nothing
Set oContainer = Nothing

WScript.Echo "Finished"

Sub EnumerateUsers(oCont)
     Dim oUser, bUser
     For Each oUser In oCont
          bUser = False
          Select Case LCase(oUser.Class)
               Case "user"

                    ' User Account Login
                    If Not IsEmpty(oUser.sAMAccountName) Then
                         If Not Instr(1,LCase(oUser.sAMAccountName),"svc",vbTextCompare) > 0 Then
                            If Not Instr(1,LCase(oUser.sAMAccountName),"admin",vbTextCompare) > 0 Then
                         If Not Instr(1,LCase(oUser.sAMAccountName),"training",vbTextCompare) > 0 Then
                                   bUser = True
                                   OutPutFile.Write oUser.sAMAccountName & vbtab
                                   ' User Account Display Name
                                   OutPutFile.Write oUser.displayName & vbtab
                                   ' User Account Last Logon Timestamp
                                   OutPutFile.Write oUser.lastLogonTimestamp & vbtab
                              End If
                         End If
                    End If
               End If

               Case "organizationalunit", "container"
                    EnumerateUsers oUser
          End Select
          If bUser Then
          End If
End Sub
LVL 12
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LambersonSoftware EngineerCommented:
Are you getting an error? Where is the code failing? Can you explain how the problem manifests itself?

BNettles73Author Commented:

I get an error at line (OutPutFile.Write oUser.lastLogonTimestamp & vbtab) ... it will create the spreadsheet and enter information for the first user but fails at the last logon timestamp ....

Scripts: C:\lastlogontimestamp.vbs
Line: 55
Char: 36
Error: object doesn't support this property or method
Code: 800A01B6
Source: Microsoft VBScript runtime error

I've used a similar script to export AD information ... I verified the attribute for lastLogonTimestamp in ADSI but am not completely sure I'm using the correct field ... I was hoping someone may be able to point me in the right direction if not ...

David LeeCommented:
Have a look at this:

It appears extremely difficult to get this information.  According to the author of the above source, lastLogon (the attribute I believe you really want) isn't replicated to each DC, forcing you to search every DC in the domain to get this piece of information.  I checked my AD using ADSIEdit and lastLogonTimestamp is "Not Set" on every user record.  I tried running the LastLogon script from the above link and it timed out before it could finish.  I have 7 outlying DCs on relatively slow links, so I guess I could never get this information.  Assuming the author is correct, and that I'm not misunderstanding something, then I've got to say that this seems to me like a huge design flaw on the part of Microsoft.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Your Guide to Achieving IT Business Success

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

BNettles73Author Commented:

Thanks BDF ... you've been a great help once again! The script I was trying to use was the one you helped me work through the last time. So rimueller's script works for me ... I can pull data from our 21 DC's and then pull it into an access database for the security team. If I may, can the following fields be set in the same script or would I need to create separate scripts for each?

1. pwdLastSet
2. accountExpires
3. badPasswordTime
4. lockoutTime

I'd also like to have the output directly to an excel document and insert Display Name and sAMAccountName, but not quite sure at what point I add the output lines.

Any help would be much appreciated!

rimueller's script -

Option Explicit

Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, 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.
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)
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 objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection

strBase = "<LDAP://" & strConfig & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 60
objCommand.Properties("Cache Results") = False

Set objRecordSet = objCommand.Execute

' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until objRecordSet.EOF
  Set objDC = _
  ReDim Preserve arrstrDCs(k)
  arrstrDCs(k) = objDC.DNSHostName
  k = k + 1

' 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"
  objCommand.CommandText = strQuery
  On Error Resume Next
  Set objRecordSet = objCommand.Execute
  If Err.Number <> 0 Then
    On Error GoTo 0
    Wscript.Echo "Domain Controller not available: " & arrstrDCs(k)
    On Error GoTo 0
    Do Until objRecordSet.EOF
      strDN = objRecordSet.Fields("distinguishedName")
      lngDate = objRecordSet.Fields("lastLogon")
      On Error Resume Next
      Set objDate = lngDate
      If Err.Number <> 0 Then
        On Error GoTo 0
        dtmDate = #1/1/1601#
        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#
          dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
            + lngLow)/600000000 - lngBias)/1440
        End If
      End If
      If objList.Exists(strDN) Then
        If dtmDate > objList(strDN) Then
          objList(strDN) = dtmDate
        End If
        objList.Add strDN, dtmDate
      End If
  End If

' Output latest lastLogon date for each user.
For Each strUser In objList
  Wscript.Echo strUser & " ; " & objList(strUser)

' Clean up.
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing

Shane Russell2nd Line Desktop SupportCommented:
Just in case you are interested I found this which has some good examples :
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.