script required to get last longon timestamp for computer accounts that are in a text file

Hi All

I have a text file that contains a large number of computer objects, i need a script that will run against this text file and give me the last logon timestamp.

We have 4 domains so will like this script to run against a spcific domain domain1.ourco.local

Thanks

Nick
LVL 5
ncomperAsked:
Who is Participating?
 
prashanthdCommented:
Try the following code..

It will automatically take the domain from where it is run.

regards
Prashanth
input_file="c:\list.txt"

Dim objRootDSE, adoConnection, adoCommand, strQuery
Dim adoRecordset, strDNSDomain, objShell, lngBiasKey
Dim lngBias, k, strDN, dtmDate, objDate
Dim strBase, strFilter, strAttributes, lngHigh, lngLow

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(input_file, 1)

' 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
Set objShell = Nothing

' Determine DNS domain from RootDSE object.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    Set objRootDSE = Nothing

Do Until objTextFile.AtEndOfStream
    
    cname=Trim(objtextfile.ReadLine)
        
    ' Use ADO to search Active Directory.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection
       
    ' Search entire domain.
    strBase = "<LDAP://" & strDNSDomain & ">"
    
    ' Filter on all user objects.
    strFilter = "(&(objectClass=computer)(cn="& cname &")"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName,lastLogonTimeStamp"
    
    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    
    ' Run the query.
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 60
    adoCommand.Properties("Cache Results") = False
    Set adoRecordset = adoCommand.Execute
    
    ' Enumerate resulting recordset.
    Do Until adoRecordset.EOF
        ' Retrieve attribute values for the user.
        strDN = adoRecordset.Fields("distinguishedName").Value
        ' Convert Integer8 value to date/time in current time zone.
        On Error Resume Next
        Set objDate = adoRecordset.Fields("lastLogonTimeStamp").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
        ' Display values for the user.
        If (dtmDate = #1/1/1601#) Then
            WScript.Echo cname & ";Never"
        Else
            WScript.Echo cname & ";" & dtmDate
        End If
        adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close
    
Loop

Open in new window

0
 
Ahmed786Commented:
Try this one, below the output will be generated in location "c:\Batch\example", you can put the required location.


Option Explicit

Dim aryContainer(500)       ' Track the name of all containers
Dim aryCN(9999,10)          ' Track the name of all users
Dim aryWhen()               ' When Created
Dim arySvCN()               ' Original context
Dim aryHomeDirectory()      ' Location of home folder
Dim aryScriptPath()         ' Location of script path
Dim arydisplayName()        ' Display Name
Dim cntLen, cntComma, cntRight
Dim cntX, cntY, cntZ
Dim cntL, cntM, cntO
Dim cntColumns
Dim flgLoop
Dim flgContainerFnd
Dim txtName, txtCN, txtSvName, tmpName
Dim usr
Dim flag
Dim objConnection
Dim objRecordSet
Dim objCommand
Dim objUser
Dim fso
Dim ts
Dim strHomeDirectory
Dim Output
Dim WshNetwork
Dim strDomainName                             ' NetBIOS Domain Name

Dim fsoHTA
Dim tsHTA
Dim CurrentDate
Dim MonthDate
Dim DayDate
Dim YearDate
Dim FileDate
Dim exFlg                   ' Exchange Object flag
Dim arrDomLevels
Dim LDAPADsPath
Dim LDAPStart
Dim cntDropHost

Dim oRoot, sConfig, oConnection, oCommand, sQuery
Dim oResults, oDC, sDNSDomain, oShell, nBiasKey
Dim nBias, k, sDCs(), sAdsPath, oDate, nDate
Dim oComputer, nLatestDate

Const FileLocation =  "c:\Batch\example"    ' Define the starting location of where you want to store the csv

Const ADS_UF_PASSWD_NOTREQD = &H0020
Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
Const ADS_UF_PASSWORD_EXPIRED = &H800000
Const ADS_UF_ACCOUNTDISABLE = &H0002

' Find all defined DC's in the domain
Sub AvailableDCs

' Obtain local Time Zone bias from machine registry.
' Watch for line wrapping.
Set oShell = CreateObject("Wscript.Shell")
nBiasKey =  oShell.RegRead("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias")
If UCase(TypeName(nBiasKey)) = "LONG" Then
  nBias = nBiasKey
ElseIf UCase(TypeName(nBiasKey)) = "VARIANT()" Then
  nBias = 0
  For k = 0 To UBound(nBiasKey)
    nBias = nBias + (nBiasKey(k) * 256^k)
  Next
End If

' Determine configuration context and
' DNS domain from RootDSE object.
Set oRoot = GetObject("LDAP://RootDSE")
sConfig = oRoot.Get("ConfigurationNamingContext")
sDNSDomain = oRoot.Get("DefaultNamingContext")

' Use ADO to search Active Directory for
' ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set oCommand = CreateObject("ADODB.Command")
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Provider = "ADsDSOObject"
oConnection.Open = "Active Directory Provider"
oCommand.ActiveConnection = oConnection

sQuery = "<LDAP://" & sConfig _
  & ">;(ObjectClass=nTDSDSA);AdsPath;subtree"

oCommand.CommandText = sQuery
oCommand.Properties("Page Size") = 100
oCommand.Properties("Timeout") = 30
oCommand.Properties("Searchscope") = 2
oCommand.Properties("Cache Results") = False

Set oResults = oCommand.Execute

' Enumerate parent objects of class nTDSDSA. Save
' Domain Controller names in dynamic array sDCs.
k = 0
'
''''' Time to find out the actual DC names, verify if online and if so save them to an array
'
Do Until oResults.EOF
  Set oDC = _
    GetObject(GetObject(oResults.Fields("AdsPath")).Parent)

    On Error Resume Next
    Set oComputer = GetObject("LDAP://" & oDC.DNSHostName)   ' Attach to see if DC is available

    if CStr(Err.Number) = 0 then     ' if no error then the DC exists
       ReDim Preserve sDCs(k)
       sDCs(k) = oDC.DNSHostName
       k = k + 1
     end if
  oResults.MoveNext
Loop

cntDropHost = inStr(sDCs(0),".") + 1                                     ' Find the start of the domain name
LDAPStart = Mid(sDCs(0),cntDropHost,(Len(sDCs(0))-cntDropHost+1))      ' Drop the host name

arrDomLevels = Split(LDAPStart, ".")                  ' Convert to LDAP Path (dc=yourdomain,dc=com...)
LDAPADsPath = "dc=" & Join(arrDomLevels, ",dc=")

'  Find The NetBIOS Name of the domain

Set WshNetwork = WScript.CreateObject("WScript.Network")
strDomainName = WshNetwork.UserDomain                     ' Store the Domain Name

End Sub

'
''''' Find out the last time on each DC
'
Sub LastTime

' Hard code LDAP AdsPath of user.
sAdsPath = arySvCN(cntL)

' Retrieve LastLogon attribute for computer on
' each Domain Controller.
nLatestDate = #1/1/1601#
oDate = #1/1/1601#

For k = 0 To Ubound(sDCs)

  On Error Resume Next
  Set oComputer = GetObject("LDAP://" & sDCs(k) & "/" & sAdsPath)

' Trap error in case LastLogon is null.
  Set oDate = oComputer.LastLogon
  On Error Resume Next

  If Err.Number <> 0 Then
    Err.Clear
    nDate = #1/1/1601#
  Else
    If (oDate.HighPart = 0) And (oDate.LowPart = 0 ) Then
      nDate = #1/1/1601#
    Else
      nDate = #1/1/1601# + (((oDate.HighPart * (2 ^ 32)) _
        + oDate.LowPart)/600000000 - nBias)/1440
    End If
  End If

  Err.Clear
  If nDate > nLatestDate Then
    nLatestDate = nDate
  End If

Next

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Routine to strip out all containers and place in the aryContainer '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub Stripper

Do
    cntLen = Len(txtName)-3
    txtName = Right(txtName,cntLen)                 ' Drops the Container Type Name
    cntComma = Instr(txtName,",") - 1               ' Find the end of the name

    If cntComma < 0 Then                            ' Last Name to process there is no comma
       cntComma = Len(txtName)
    End If

    txtCN = Left(txtName,cntComma)                  ' Pull the Name out of the Distinguished Name

    flgContainerFnd = "N"


    For cntL = 0 to 500                             ' Does this current Container exist?
       If aryContainer(cntL) = "" Then              ' If current location is blank then add it to the table
          aryContainer(cntL) = txtCN
          Exit For
       End If

       If aryContainer(cntL) = txtCN Then           ' OU found
          Exit For
       End if
    Next

    aryCN(cntX, cntY) = cntL                        ' Store location of OU
    cntY = cntY + 1                                 ' increment counter

    cntComma = Instr(txtName,",")                   ' If equal to zero then all done

    If cntComma > 0 Then
       cntRight = Len(txtName) - (cntComma)         ' Get to start of next part of name
       txtName = Right(txtName, cntRight)           ' Purge CN name
       flgLoop = "Y"
    Else
       flgLoop = "N"                                ' Set all done flag
    End If

Loop Until flgLoop = "N"

End Sub


'   This is the start of the program
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Main Code of Program                                             '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''



Call AvailableDCs                                     ' Go get the DC's in the domain

Set objConnection = CreateObject("ADODB.Connection")  ' Create a Connection object in memory
objConnection.Open "Provider=ADsDSOObject;"           ' Open the Connection object using the ADSI OLE DB provider

Set objCommand = CreateObject("ADODB.Command")  'Create an ADO Command object in memory, and assign the Command _
objCommand.ActiveConnection = objConnection     ' object’s ActiveConnection property to the Connection object

objCommand.Properties("Page Size") = 100
objCommand.Properties("Size Limit") = 3000

objCommand.CommandText = _
   "<LDAP://" & LDAPADsPath &  ">;(objectCategory=user);sAMAccountName,distinguishedName,name,whenCreated,homeDirectory,scriptPath,displayName;subtree"

Set objRecordSet = objCommand.Execute            ' Run the query by calling the Execute method of the Command object

cntX = 0
cntY = 0

'
''''' Do an LDAP call and get all users in AD and save the users data
'
While Not objRecordSet.EOF
    txtName =  lcase(objRecordSet.Fields("distinguishedName"))         ' Access each record in objRecordSet
    txtSvName = txtName

    ReDim Preserve arySvCN(cntX)
    ReDim Preserve aryWhen(cntX)                                ' Save when account created
    ReDim Preserve aryHomeDirectory(cntX)
    ReDim Preserve aryScriptPath(cntX)
    ReDim Preserve arydisplayName(cntX)

    aryWhen(cntX)          = lcase(objRecordSet.Fields("whenCreated"))
    aryHomeDirectory(cntX) = lcase(objRecordSet.Fields("homeDirectory"))
    aryScriptPath(cntX)    = lcase(objRecordSet.Fields("scriptPath"))
    arydisplayName(cntX)   = lcase(objRecordSet.Fields("displayName"))

    cntLen = Len(txtName)
    txtName = Left(txtName,(cntLen-18))             ' Provides the name w/o dc=Your Domain,dc=com
    cntLen = Len(txtName)-3
    txtName = Right(txtName,cntLen)                 ' Drops the Container Type Name
    cntComma = Instr(txtName,",") - 1               ' Find the end of the name
    txtCN = Left(txtName,cntComma)                  ' Pull the Name out of the Distinguished Name

    aryCN(cntX, cntY) = lcase(objRecordSet.Fields("sAMAccountName"))       ' Save Name
    arySvCN(cntX) = txtSvName                       ' Save Distinguished Name
    cntY = cntY + 1                                 ' increment table counter
    cntRight = Len(txtName) - (cntComma + 1)        ' Get to start of next part of name
    txtName = Right(txtName,cntRight)               ' Purge CN name

    Call Stripper                                   ' Build table of the context of the user

    cntX = cntX + 1
    cntY = 0

    objRecordSet.MoveNext                       ' Move to next user
Wend

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Create a file using todays date as part of the file name               '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
CurrentDate = Date
YearDate = Year(CurrentDate)
MonthDate = Month(CurrentDate)
If MonthDate < 9 then
  MonthDate = "0" & MonthDate
End If
DayDate = Day(CurrentDate)
If DayDate < 9 then
  DayDate = "0" & DayDate
End If

FileDate = FileLocation & YearDate & MonthDate & DayDate & "_accts.csv"

Set fso = CreateObject("Scripting.FileSystemObject")
set ts =  fso.CreateTextFile(FileDate, True)         ' Create the file

For cntL = 0 to 500                                ' Find out how many columns used
   If aryContainer(cntL) = "" Then
      Exit For
   End If
Next

cntColumns = cntL

ts.write("Logon Name, Context")
ts.write(", Header OU")                            ' Remove for multiple OU's
ts.writeline(", Last Logon Date, Creation Date, Home Folder, Script, Display Name, Password Not Needed, Password Does Not Expire, Expired Password, Account Is Disabled")

'
''''' Finally output the data (This system is only setup for a max of 10,000 users
'
For cntL = 0 to 9999                                ' Cycle through all users found
   If aryCN(cntL,0) = "" Then                       ' Quit once end found
      Exit For
   End If

   'If this is an Replicated Exchange Object, drop it
   exFlg = InStr(1,arySvCN(cntL), "adc_replication",1)
   If exFlg = 0 Then

      ts.write(aryCN(cntL,0)) & ", "                   ' Output users logon name

      'Drop all comma's in the context
      tmpName = Replace(arySvCN(cntL), ",", " ")
      ts.write(tmpName) & ", "                         ' Output full context of user
      ts.write(aryContainer(aryCN(cntL,1)))            ' Output users Home OU

      Call LastTime                                    ' Sniff Out Last Time logged on

      If nLatestDate <> "1/1/1601" Then
         ts.write(", " & nLatestDate)
      Else
         ts.write(", ")
      End If
      ts.write(", ")                                    ' Date Account Was Created
      ts.write(aryWhen(cntL))
      ts.write(", ")                                    ' Home folder location
      If aryHomeDirectory(cntL) > "" Then
         ts.write(aryHomeDirectory(cntL))
      Else
         ts.write(" ")
      End If

      ts.write(", ")

      If aryScriptPath(cntL) > "" Then
         ts.write(aryScriptPath(cntL))
      Else
         ts.write(" ")
      End If

      ts.write(", ")

      If arydisplayName(cntL) > "" Then
         ts.write(arydisplayName(cntL))
      Else
         ts.write(" ")
      End If

         on error resume next
         Set usr = GetObject("WinNT://" & strDomainName & "/" & aryCN(cntL,0))
         flag = usr.Get("UserFlags")

         If flag AND ADS_UF_PASSWD_NOTREQD Then
             ts.write(", y")
         Else
             ts.write(", ")
         End If

         If flag AND ADS_UF_DONT_EXPIRE_PASSWD Then
             ts.write(", y")
         Else
             ts.write(", ")
         End If

         If flag AND ADS_UF_PASSWORD_EXPIRED Then
             ts.write(", y")
         Else
             ts.write(", ")
         End If

         If flag AND ADS_UF_ACCOUNTDISABLE Then
             ts.write(", y")
         Else
             ts.write(", ")
         End If

      ts.writeline()                                   ' Start a newline

   End If

Next

objConnection.Close
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.