• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2198
  • Last Modified:

Last Login Script

I want an interactive script to check the last time a user logged onto ACtive Directory... The result should give me their name, last logon time & date... If the script is not interactive, give me the output in a text file format... with the details username, last logon time & date!....

note, I have never used Windows Scripting before....
0
NickyPower
Asked:
NickyPower
1 Solution
 
KREDIERSCommented:
Download a demo of hyena and use the exporter function.
It will give you the full list with all the info you need.
0
 
RobSampsonCommented:
Hi, you can Excel for your interactive component.  In Excel, have these columns:
Machine or User                 Type                      Machine Ping               Last Logon        Up Time (hours)
D09790RING                       Machine
rsampson                            User

Column A: you enter a computer name or username
Column B: you enter "machine" or "user" depending on the object type
Column C: you automatically get the Ping status
Column D: you automatically get the LastLogon time
Column E: you automatically get the up time in hours

Then, open the Visual Basic Editor, right click "This Workbook" and click Insert --> Module.  Paste this code there.  Then you must click Tools --> References, tick Microsoft Scripting Runtime, and click OK:

Sub ManualPingRun()
    strColumn = InputBox("Which letter column do you want to get LastLogon for?", "Column Letter")
   
    For intRow = 2 To Cells(65536, strColumn).End(xlUp).Row
        strType = Cells(intRow, Asc(UCase(strColumn)) - 63).Value
        If LCase(strType) = LCase("Machine") Then
            Cells(intRow, Asc(UCase(strColumn)) - 62).Value = GetPingInfo(Cells(intRow, strColumn).Value)
            If Cells(intRow, Asc(UCase(strColumn)) - 62).Value = "Success" Then
                strBootUpTime = GetBootUpTime(Cells(intRow, strColumn).Value)
                Select Case Int(Mid(strBootUpTime, 5, 2))
                    Case 1
                        strMonth = "JAN"
                    Case 2
                        strMonth = "FEB"
                    Case 3
                        strMonth = "MAR"
                    Case 4
                        strMonth = "APR"
                    Case 5
                        strMonth = "MAY"
                    Case 6
                        strMonth = "JUN"
                    Case 7
                        strMonth = "JUL"
                    Case 8
                        strMonth = "AUG"
                    Case 9
                        strMonth = "SEP"
                    Case 10
                        strMonth = "OCT"
                    Case 11
                        strMonth = "NOV"
                    Case 12
                        strMonth = "DEC"
                End Select
                dteBootUpTime = CDate(Mid(strBootUpTime, 7, 2) & "-" & strMonth & "-" & Left(strBootUpTime, 4) & _
                    " " & Mid(strBootUpTime, 9, 2) & ":" & Mid(strBootUpTime, 11, 2) & ":" & Mid(strBootUpTime, 13, 2))
                'MsgBox Cells(intRow, strColumn).Value & vbCrLf & strBootUpTime & vbCrLf & dteBootUpTime
                Cells(intRow, Asc(UCase(strColumn)) - 60).Value = DateDiff("h", dteBootUpTime, Now)
            End If
        End If
        Cells(intRow, Asc(UCase(strColumn)) - 61).Value = GetObjectLastLogon(Cells(intRow, strColumn).Value, strType)
    Next
   
    MsgBox "Finished"
End Sub

Function GetPingInfo(strComputer)
    Dim objShell, boolCode
    Set objShell = CreateObject("WScript.Shell")
    boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
    If boolCode = 0 Then
        GetPingInfo = "Success"
    Else
        GetPingInfo = "Failure"
    End If
End Function

Function GetObjectLastLogon(strComputer, strObjectType)

    Dim objRootDSE, objComputers, objDomainControllers, objDomainController, objFileSystem, objFile
    Dim strUsername, strAccountState, strDN, strDisplayName
    Dim dtmLastLogon, dtmRuntime
     
    Set objRootDSE = GetObject("LDAP://RootDSE")

    Set objComputers = CreateObject("Scripting.Dictionary")

    ' Get the DC List
     
    Set objDomainControllers = GetObject("LDAP://OU=Domain Controllers," & _
          objRootDSE.Get("defaultNamingContext"))
    objDomainControllers.Filter = Array("computer")
   
    'strResults = "LastLogon for " & strComputer
    For Each objDomainController In objDomainControllers
        ' This sub directly modifies the dictionary object
        dtmLastLogon = GetLastLogon(objDomainController, strComputer, strObjectType)
        'strResults = strResults & vbCrLf & objDomainController.Name & ": " & dtmLastLogon
        If objComputers(strComputer) = "UNKNOWN" Then objComputers.Remove strComputer
        If objComputers.Exists(strComputer) Then
            If dtmLastLogon <> "UNKNOWN" And dtmLastLogon > objComputers(strComputer) Then
                objComputers(strComputer) = dtmLastLogon
            End If
        Else
            objComputers.Add strComputer, dtmLastLogon
        End If
    Next
    'MsgBox strResults
   
    Set objDomainControllers = Nothing
    Set objRootDSE = Nothing
   
    If Trim(objComputers(strComputer)) = "" Then objComputers(strComputer) = "UNKNOWN"
    GetObjectLastLogon = objComputers(strComputer)
   
    Set objComputers = Nothing

End Function
 
Function GetLastLogon(objDomainController, strComputer, strObjectType)
    Const ADS_SCOPE_SUBTREE = 2
    Const ADS_UF_ACCOUNTDISABLE = &H2
 
    Dim objConnection, objCommand, objRecordSet, objRootDSE, objLastLogon
    Dim strDCName, strUsername, strDN, strDisplayName
    Dim intUAC, intLogonTime
    Dim dtmLastLogon
 
    Set objComputers = CreateObject("Scripting.Dictionary")
 
    strDCName = Mid(objDomainController.Name, 4, Len(objDomainController.Name))
 
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
   
    Set objCommand = CreateObject("ADODB.Command")
    Set objCommand.ActiveConnection = objConnection
   
    Set objRootDSE = GetObject("LDAP://RootDSE")
    If LCase(strObjectType) = LCase("Machine") Then
        objCommand.CommandText = "SELECT lastLogon " & _
            "FROM 'LDAP://" & strDCName & "/" & objRootDSE.Get("defaultNamingContext") & "' " & _
            "WHERE objectClass='computer' AND cn='" & strComputer & "'"
    Else
        objCommand.CommandText = "SELECT lastLogon " & _
            "FROM 'LDAP://" & strDCName & "/" & objRootDSE.Get("defaultNamingContext") & "' " & _
            "WHERE objectClass='user' AND samAccountName='" & strComputer & "' OR CN='" & strComputer & "' OR DisplayName='" & strComputer & "'"
    End If
    Set objRootDSE = Nothing
   
    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Timeout") = 600
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    objCommand.Properties("Cache Results") = False
 
    Set objRecordSet = objCommand.Execute
   
    dtmLastLogon = ""
    While Not objRecordSet.EOF
        dtmLastLogon = ""
        On Error Resume Next
        objLastLogon = objRecordSet.Fields("lastLogon")
 
        intLogonTime = objLastLogon.HighPart * (2 ^ 32) + objLastLogon.LowPart
        intLogonTime = intLogonTime / 600000000
        intLogonTime = intLogonTime / 1440
        dtmLastLogon = intLogonTime + #1/1/1601#
 
        Set objLastLogon = Nothing
        On Error GoTo 0
 
        If dtmLastLogon <> #1/1/1601# Then
            ' wscript.echo strComputer & " LastLogon=" & dtmLastLogon
            If objComputers.Exists(strComputer) Then
                If dtmLastLogon > objComputers(strComputer) Then
                    objComputers(strComputer) = dtmLastLogon
                End If
            Else
                objComputers.Add strComputer, dtmLastLogon
            End If
        End If
 
        objRecordSet.MoveNext
    Wend
 
    Set objRecordSet = Nothing
    Set objCommand = Nothing
    Set objConnection = Nothing
   
    If dtmLastLogon = "" Then
        GetLastLogon = "UNKNOWN"
    ElseIf objComputers.Exists(strComputer) Then
        GetLastLogon = objComputers(strComputer)
    Else
        GetLastLogon = "UNKNOWN"
    End If
   
    Set objComputers = Nothing
   
End Function

Function GetBootUpTime(strComputer)

    Dim objItem
    Dim objWMIService, colItems
    Dim strBootUpTime

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select LastBootUpTime from Win32_OperatingSystem", , 48)
    For Each objItem In colItems
       strBootUpTime = Left(objItem.LastBootUpTime, InStr(objItem.LastBootUpTime, "+") - 1)
    Next

    GetBootUpTime = strBootUpTime

End Function


Then, go back to Excel, enter a computer or user in column A, enter the type in Column B, run the ManualPingRun macro, enter A and click OK.

Regards,

Rob.
0
 
Chris DentPowerShell DeveloperCommented:

Hey Rob,

Bit curious about your Ping function (if you don't mind me being nosy :))

Doesn't the Return Code you have here:

    If boolCode = 0 Then
        GetPingInfo = "Success"
    Else
        GetPingInfo = "Failure"
    End If

Only return 0 if the command fails to execute rather than checking the return from ping? That is, it could successfully execute, but return "No Reply"?

Chris
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
RobSampsonCommented:
Hey Chris,

Not from my testing.....from any test that I have run, it *only* returns zero if it gets a reply.
Even if it can resolve the host name but still times out, it returns 1.

If you can find a test case where this is not the case *please* let me know, because otherwise I've been leading a few people "down the garden path"  :-o

Regards,

Rob.
0
 
Chris DentPowerShell DeveloperCommented:

Nice, I like that one, simplifies my version somewhat :)

Chris
0
 
NickyPowerAuthor Commented:
apologies to the delay...
0
 
RobSampsonCommented:
Thanks for the grade.

Regards,

Rob.
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now