Re: Users last logon info from logon script

From: monk (monk_at_discussions.microsoft.com)
Date: 04/23/05


Date: Sat, 23 Apr 2005 06:27:02 -0700

Hi Torgeir,

I put this line in the users logon script: wscript
\\dc1\netlogon\lastlogon.vbs. Then when users logon, they get a popup window
tells them the last logn time - it all seemed good. But, the last logon time
that is in the popup window is actually the cyrrently logon time!?

If I run the script manually, it shows the last logon time. Even when I run
the logon script manuelly, it still shows the last logon time. But when users
logon, the popup window shows the currect logon time.

I guess it is because Windows update the lastlogon attribute once a user
logs on to the domain? How can I prevent this? How can I get the correct LAST
logon time?

Thanks a lot.

"Torgeir Bakken (MVP)" wrote:

> monk wrote:
>
> > After testing, I found out this is not what I wanted --
> >
> > This script shows the local computer time when the users log on. what I want
> > is: to retrieve the LastLogon AD Scheme attributes from all of the domain
> > controllers and compare them and show users their real previous logon time to
> > the domain. (not the PC)
> Hi
>
> Did you read this part of my script:
>
> ' point to user's home folder, or another common share
> ' where the users have write access, UNC path is allowed also
> sDateLogFile = "C:\LastLoggedOn_" & oWshNet.Username & ".log"
>
> If you change it to use a location on a central server, it will
> be the domain logon time and not PC.
>
>
> But if you absolutely want to enumerate and connect to all domain
> controllers, below is modified version of the script in this link:
> http://www.rlmueller.net/Last%20Logon.htm
>
> Note that you risk that a lot of extra time is added to the logon time.
> For me it takes 40 seconds to run the script below. This is avoided if
> you use the first script I gave you.
>
>
> '--------------------8<----------------------
> ' LastLogon.vbs
> ' VBScript program to determine when current user last logged on
> ' in the domain.
> '
> ' ----------------------------------------------------------------------
> ' Copyright (c) 2002 Richard L. Mueller
> ' Hilltop Lab web site - http://www.rlmueller.net
> ' Version 1.0 - December 7, 2002
> ' Version 1.1 - January 17, 2003 - Account for null value for lastLogon.
> ' Version 1.2 - January 23, 2003 - Account for DC not available.
> ' Version 1.3 - February 3, 2003 - Retrieve users but not contacts.
> ' Version 1.4 - February 19, 2003 - Standardize Hungarian notation.
> ' Version 1.5 - March 11, 2003 - Remove SearchScope property.
> ' Version 1.6 - May 9, 2003 - Account for error in IADsLargeInteger
> ' property methods HighPart and LowPart.
> ' Version 1.7 - January 25, 2004 - Modify error trapping.
> '
> ' Modified 2004-12-20 by Torgeir Bakken to output user's display
> ' name as well.
> '
> ' Modified 2005-02-08 by Torgeir Bakken to only search for current user.
> '
> '
> ' Because the lastLogon attribute is not replicated, every Domain
> ' Controller in the domain must be queried to find the latest lastLogon
> ' date for each user. The lastest date found is kept in a dictionary
> ' object. The program first uses ADO to search the domain for all Domain
> ' Controllers. The AdsPath of each Domain Controller is saved in an
> ' array. Then, for each Domain Controller, ADO is used to search the
> ' copy of Active Directory on that Domain Controller for all user
> ' objects and return the lastLogon attribute. The lastLogon attribute is
> ' a 64-bit number representing the number of 100 nanosecond intervals
> ' since 12:00 am January 1, 1601. This value is converted to a date. The
> ' last logon date is in UTC (Coordinated Univeral Time). It must be
> ' adjusted by the Time Zone bias in the machine registry to convert to
> ' local time.
> '
> ' You have a royalty-free right to use, modify, reproduce, and
> ' distribute this script file in any way you find useful, provided that
> ' you agree that the copyright owner above has no warranty, obligations,
> ' or liability for such use.
>
> 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
> Dim strDisplayName, strUserInfo
> Dim objWshNet, strSAMAccountName
>
>
> ' 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)
> 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 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 = _
> GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
> ReDim Preserve arrstrDCs(k)
> arrstrDCs(k) = objDC.DNSHostName
> k = k + 1
> objRecordSet.MoveNext
> Loop
>
> Set objWshNet = CreateObject("WScript.Network")
> strSAMAccountName = objWshNet.Username
>
> ' 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)(sAMAccountName=" _
> & strSAMAccountName & "))"
> strAttributes = "distinguishedName,lastLogon,displayName"
> 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)
> Else
> On Error GoTo 0
> Do Until objRecordSet.EOF
> strDisplayName = objRecordSet.Fields("displayName")
> strDN = objRecordSet.Fields("distinguishedName")
> lngDate = objRecordSet.Fields("lastLogon")
> strUserInfo = strDN & ", " & strDisplayName
> On Error Resume Next
> Set objDate = lngDate
> 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(strUserInfo) Then
> If dtmDate > objList(strUserInfo) Then
> objList(strUserInfo) = dtmDate
> End If
> Else
> objList.Add strUserInfo, dtmDate
> End If
> objRecordSet.MoveNext
> Loop
> End If
> Next
>
> ' Output latest lastLogon date for each user.
> For Each strUser In objList
> Wscript.Echo strUser & " ; " & objList(strUser)
> Next
>
> ' Clean up.
> objConnection.Close
> Set objRootDSE = Nothing
> Set objConnection = Nothing
> Set objCommand = Nothing
> Set objRecordSet = Nothing
> Set objDC = Nothing
> Set objDate = Nothing
> Set objList = Nothing
> Set objShell = Nothing
>
> '--------------------8<----------------------
>
>
>
>
>
> --
> torgeir, Microsoft MVP Scripting and WMI, Porsgrunn Norway
> Administration scripting examples and an ONLINE version of
> the 1328 page Scripting Guide:
> http://www.microsoft.com/technet/scriptcenter/default.mspx
>



Relevant Pages

  • Re: Log file!
    ... Here is an example VBScript program to retrieve the lastLogon values for all ... logon and logoff info, you can assign Logon and Logoff scripts using Group ... This script appends a line to a log file in a shared location. ...
    (microsoft.public.windows.server.active_directory)
  • Re: "Last logon time" & "Last time the account was authenticated b
    ... I do have a script that extracts last logon details ... the updated Last logon time. ... corresponds to the value of the lastLogon attribute. ...
    (microsoft.public.windows.server.active_directory)
  • Re: slow logon
    ... in the logon time have been reduced so far. ... update the time for the clients that talk to the dc as the logon server. ... start up script in AD to apply updates to the clients machines which is ...
    (microsoft.public.windows.server.active_directory)
  • Logon Script Causing Laptops To Hang - Problems in script?
    ... I'm using the following script to map drives, ... functions when users logon to our domain. ... 'Disconnects Drives This assures everyone has the same drive mappings. ... objNetwork.MapNetworkDrive strTrainDrv, strPath ...
    (microsoft.public.scripting.vbscript)
  • Re: SMSLOGON Share point
    ... you may be able to run smsls.bat from the nt4 domain controller ... > clients as you would specify the logon point in the script e.g. ...
    (microsoft.public.sms.admin)