How can I pop up a window to show domain users last logon info when they
logon to the domain?

Re: Users last logon info from logon script by Torgeir

Torgeir
Sat Feb 05 16:14:02 CST 2005

monk wrote:

> How can I pop up a window to show domain users last logon info
> when they logon to the domain?
Hi

You could put the following into a VBScript based logon script. First
time you run the script it will not display any information, it will
only create the file in the variable sDateLogFile (change the path to
something that fits your environment).


'--------------------8<----------------------

Const ForReading = 1
Const OpenAsASCII = 0
Const FailIfNotExist = 0
Const OverwriteIfExist = -1

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oWshNet = CreateObject("WScript.Network")

' point to user's home folder, or another common share
' where the users have write access, UNC path is allowed also
sDateLogFile = "H:\LastLoggedOn_" & oWshNet.Username & ".log"

If oFSO.FileExists(sDateLogFile) Then
Set fFile = oFSO.OpenTextFile(sDateLogFile, _
ForReading, FailIfNotExist, OpenAsASCII)
sDate = fFile.ReadLine
fFile.Close
MsgBox "You last logged on to the domain at " & sDate, _
vbInformation + vbSystemModal, "Logon status"
End If

Set fFile = oFSO.CreateTextFile(sDateLogFile, OverwriteIfExist, OpenAsASCII)
fFile.WriteLine Now
fFile.Close

'--------------------8<----------------------


WSH 5.6 documentation (local help file) can be downloaded from here
if you haven't got it already:
http://msdn.microsoft.com/downloads/list/webdev.asp



--
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

Re: Users last logon info from logon script by Torgeir

Torgeir
Sat Feb 05 16:25:07 CST 2005

Torgeir Bakken (MVP) wrote:

> monk wrote:
>
>> How can I pop up a window to show domain users last logon info
>> when they logon to the domain?
>
> Hi
>
> You could put the following into a VBScript based logon script. First
> time you run the script it will not display any information, it will
> only create the file in the variable sDateLogFile (change the path to
> something that fits your environment).
Hi

A little rewrite of the script below so the time written to the file
isn't depentent on how long the message box is displayed.

Also, if you only want the message to be displayed x number of seconds
if the user does not click "OK", replace the MsgBox line with this:

Set oShell = CreateObject("WScript.Shell")
oShell.Popup "You last logged on to the domain at " & sDate, 5, _
"Logon status", vbInformation + vbSystemModal


'--------------------8<----------------------

Const ForReading = 1
Const OpenAsASCII = 0
Const FailIfNotExist = 0
Const OverwriteIfExist = -1

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oWshNet = CreateObject("WScript.Network")

' 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"

dNow = Now
If oFSO.FileExists(sDateLogFile) Then
Set fFile = oFSO.OpenTextFile(sDateLogFile, _
ForReading, FailIfNotExist, OpenAsASCII)
sDate = fFile.ReadLine
fFile.Close
MsgBox "You last logged on to the domain at " & sDate, _
vbInformation + vbSystemModal, "Logon status"
End If

Set fFile = oFSO.CreateTextFile(sDateLogFile, OverwriteIfExist, OpenAsASCII)
fFile.WriteLine dNow
fFile.Close

'--------------------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

Re: Users last logon info from logon script by monk

monk
Mon Feb 07 07:49:01 CST 2005

Beautiful!!!

Does this mean I need install the Windows Scriping Host on the domain
controllers and users' PCs?

Thanks.

"Torgeir Bakken (MVP)" wrote:

> Torgeir Bakken (MVP) wrote:
>
> > monk wrote:
> >
> >> How can I pop up a window to show domain users last logon info
> >> when they logon to the domain?
> >
> > Hi
> >
> > You could put the following into a VBScript based logon script. First
> > time you run the script it will not display any information, it will
> > only create the file in the variable sDateLogFile (change the path to
> > something that fits your environment).
> Hi
>
> A little rewrite of the script below so the time written to the file
> isn't depentent on how long the message box is displayed.
>
> Also, if you only want the message to be displayed x number of seconds
> if the user does not click "OK", replace the MsgBox line with this:
>
> Set oShell = CreateObject("WScript.Shell")
> oShell.Popup "You last logged on to the domain at " & sDate, 5, _
> "Logon status", vbInformation + vbSystemModal
>
>
> '--------------------8<----------------------
>
> Const ForReading = 1
> Const OpenAsASCII = 0
> Const FailIfNotExist = 0
> Const OverwriteIfExist = -1
>
> Set oFSO = CreateObject("Scripting.FileSystemObject")
> Set oWshNet = CreateObject("WScript.Network")
>
> ' 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"
>
> dNow = Now
> If oFSO.FileExists(sDateLogFile) Then
> Set fFile = oFSO.OpenTextFile(sDateLogFile, _
> ForReading, FailIfNotExist, OpenAsASCII)
> sDate = fFile.ReadLine
> fFile.Close
> MsgBox "You last logged on to the domain at " & sDate, _
> vbInformation + vbSystemModal, "Logon status"
> End If
>
> Set fFile = oFSO.CreateTextFile(sDateLogFile, OverwriteIfExist, OpenAsASCII)
> fFile.WriteLine dNow
> fFile.Close
>
> '--------------------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
>

Re: Users last logon info from logon script by monk

monk
Mon Feb 07 08:21:04 CST 2005

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)

Thanks a lot!

"Torgeir Bakken (MVP)" wrote:

> Torgeir Bakken (MVP) wrote:
>
> > monk wrote:
> >
> >> How can I pop up a window to show domain users last logon info
> >> when they logon to the domain?
> >
> > Hi
> >
> > You could put the following into a VBScript based logon script. First
> > time you run the script it will not display any information, it will
> > only create the file in the variable sDateLogFile (change the path to
> > something that fits your environment).
> Hi
>
> A little rewrite of the script below so the time written to the file
> isn't depentent on how long the message box is displayed.
>
> Also, if you only want the message to be displayed x number of seconds
> if the user does not click "OK", replace the MsgBox line with this:
>
> Set oShell = CreateObject("WScript.Shell")
> oShell.Popup "You last logged on to the domain at " & sDate, 5, _
> "Logon status", vbInformation + vbSystemModal
>
>
> '--------------------8<----------------------
>
> Const ForReading = 1
> Const OpenAsASCII = 0
> Const FailIfNotExist = 0
> Const OverwriteIfExist = -1
>
> Set oFSO = CreateObject("Scripting.FileSystemObject")
> Set oWshNet = CreateObject("WScript.Network")
>
> ' 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"
>
> dNow = Now
> If oFSO.FileExists(sDateLogFile) Then
> Set fFile = oFSO.OpenTextFile(sDateLogFile, _
> ForReading, FailIfNotExist, OpenAsASCII)
> sDate = fFile.ReadLine
> fFile.Close
> MsgBox "You last logged on to the domain at " & sDate, _
> vbInformation + vbSystemModal, "Logon status"
> End If
>
> Set fFile = oFSO.CreateTextFile(sDateLogFile, OverwriteIfExist, OpenAsASCII)
> fFile.WriteLine dNow
> fFile.Close
>
> '--------------------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
>

Re: Users last logon info from logon script by Torgeir

Torgeir
Mon Feb 07 18:58:41 CST 2005

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

Re: Users last logon info from logon script by monk

monk
Mon Feb 07 19:53:02 CST 2005

Hi,

Your first acript is really neat! I guess it was me didn't explain my
situation clearly. Here is: the problem is, some admin could login as this
user and do some damage then modify the log. I hope by using AD attribute,
there is no way to modify the AD.(you see, I am doing this script really to
against admins.)

I assume your new scirpt will pop up a message to the currently logged on
user and tell them their last logon time.

I will test it tomorrow.

Really, really appreciate your time and help!

"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
>

Re: Users last logon info from logon script by monk

monk
Sat Apr 23 08:27:02 CDT 2005

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
>

Re: Users last logon info from logon script by Torgeir

Torgeir
Sat Apr 23 11:51:40 CDT 2005

monk wrote:

> 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?

You can't.

> How can I get the correct LAST logon time?

You need to save the value obtained by the script somewhere, and
display the saved value at next logon. You can save the value in a
file on a file server, or in an unused attribute in the user object
in AD.



--
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

Re: Users last logon info from logon script by monk

monk
Mon Apr 25 07:30:03 CDT 2005

Hi Torgeir,

Can you show me how to "save the value in an unused attribte in the user
object in AD", then retrive it to a popup window during logon process?

Thanks a lot!

"Torgeir Bakken (MVP)" wrote:

> monk wrote:
>
> > 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?
>
> You can't.
>
> > How can I get the correct LAST logon time?
>
> You need to save the value obtained by the script somewhere, and
> display the saved value at next logon. You can save the value in a
> file on a file server, or in an unused attribute in the user object
> in AD.
>
>
>
> --
> 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
>

Re: Users last logon info from logon script by monk

monk
Tue May 10 09:28:02 CDT 2005

Hi Torgeir,

This script is very smart. The only concern is that a Admin could access
this file and change the date and time. I guess the best way is to compare
the date time within this file to the date and time of the file creation (
that the system gives, which cannot be comprimised.).

How do I do that?
Thanks.

"Torgeir Bakken (MVP)" wrote:

> Torgeir Bakken (MVP) wrote:
>
> > monk wrote:
> >
> >> How can I pop up a window to show domain users last logon info
> >> when they logon to the domain?
> >
> > Hi
> >
> > You could put the following into a VBScript based logon script. First
> > time you run the script it will not display any information, it will
> > only create the file in the variable sDateLogFile (change the path to
> > something that fits your environment).
> Hi
>
> A little rewrite of the script below so the time written to the file
> isn't depentent on how long the message box is displayed.
>
> Also, if you only want the message to be displayed x number of seconds
> if the user does not click "OK", replace the MsgBox line with this:
>
> Set oShell = CreateObject("WScript.Shell")
> oShell.Popup "You last logged on to the domain at " & sDate, 5, _
> "Logon status", vbInformation + vbSystemModal
>
>
> '--------------------8<----------------------
>
> Const ForReading = 1
> Const OpenAsASCII = 0
> Const FailIfNotExist = 0
> Const OverwriteIfExist = -1
>
> Set oFSO = CreateObject("Scripting.FileSystemObject")
> Set oWshNet = CreateObject("WScript.Network")
>
> ' 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"
>
> dNow = Now
> If oFSO.FileExists(sDateLogFile) Then
> Set fFile = oFSO.OpenTextFile(sDateLogFile, _
> ForReading, FailIfNotExist, OpenAsASCII)
> sDate = fFile.ReadLine
> fFile.Close
> MsgBox "You last logged on to the domain at " & sDate, _
> vbInformation + vbSystemModal, "Logon status"
> End If
>
> Set fFile = oFSO.CreateTextFile(sDateLogFile, OverwriteIfExist, OpenAsASCII)
> fFile.WriteLine dNow
> fFile.Close
>
> '--------------------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
>