Re: lastLogon
- From: "Richard Mueller" <rlmueller-NOSPAM@xxxxxxxxxxxxxxxxxxxx>
- Date: Thu, 5 Oct 2006 20:22:54 -0500
Hi,
This is a common problem. Most likely you know the NT name of the user,
which is not the same as the Common Name (the value of the cn attribute).
This is often the name the user uses to logon. It is the value of the
sAMAccountName attribute. In ADUC it is called the "pre-Windows 2000 logon
name". If you know the sAMAccountName, you can use the NameTranslate object
to convert this (in conjunction with the NetBIOS name of the domain) into
the Distinguished Name (the value of which includes the cn and the OU
information). For information on using NameTranslate, see this link:
http://www.rlmueller.net/NameTranslateFAQ.htm
In your first code example, your search filter looks for users that have a
specified value for cn (the Common Name). This will only work if there is
only one such user. The cn attribute only needs to be unique in the
container or OU. There can be several objects in the domain with the same
Common Name, and your code will retrieve all user objects that have the
specifed Common Name. If the value you have is the NT name of the user, you
can retrieve the unique object that has that sAMAccountName. Your filter
would be (watch line wrapping):
strFilter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=Joe
Johnson))"
If the name value you have is really the cn, then either you must depend on
it being unique, or you need some other way to uniquely identify the user.
In the general case, it cannot be done without some other information (the
value of another attribute, or the DN of the OU/Container the object resides
in).
The second code example you gave retrieves the value of lastLogon on only
one Domain Controller (DC). This will only be valid if you have one DC, or
you somehow know the specified user always authenticates to the same DC
(which isn't really knowable). You will get a value, but you do not know if
it is the largest (latest) value in the domain.
The approach you take depends a bit on your purpose. The lastLogon VBScript
I linked retrieves the last logon dates for all users. I figure if I have to
query every DC I might was well get values for all users. If you only want
the lastLogon for one user, it can be revised for this, assuming you know
the value of the sAMAccountName (the NT name of the user). In the loop where
ADO is used to query every DC, the existing filter in LastLogon.vbs is:
strFilter = "(&(objectCategory=person)(objectClass=user))"
Again, this could be revised for just one user as follows:
strNTName = "Joe Johnson"
strFilter = "(&(objectCategory=person)(objectClass=user)" _
& "(sAMAccountName=" & strNTName & "))"
If "Joe Johnson" is the common name of the user, there is no good solution.
I think the best answer is to use LastLogon.vbs as is, redirect the output
to a text file, read the text file into a spread***, and find the user you
want.
--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
"Fan" <bkhung@xxxxxxxxxxx> wrote in message
news:Oyvp4LN6GHA.4816@xxxxxxxxxxxxxxxxxxxxxxx
Hello, Richard,
As I went over the sample scripts given by your links, I found that it
works fine. But one disadvantage of such method is that you have to SPELL
out the OU and our users are scratched all over many different OUs. The
sample script code I attached previously does not need to include the OU
so it's easy to get to the user. Do you have any solution to resolve the
'lastLogon' problem within the code I have (which is using
"ADODB.Connection" rather than the "GetObject("...") to tab to the
dababase)? Please see my previous message for the script code. Here is the
simple code that works but requires the OU phase:
'=========== works but requires OU... =========================
Set objUser = GetObject("LDAP://cn=Joe Johnson,ou=IT dc=MyDomain, dc=com")
Set objLastLogon = objUser.Get("lastLogon")
intLastLogonTime = objLastLogon.HighPart * (2^32) + objLastLogon.LowPart
intLastLogonTime = intLastLogonTime / (60 * 10000000)
intLastLogonTime = intLastLogonTime / 1440
Wscript.Echo "Last logon time: " & intLastLogonTime + #1/1/1601#
'=======================================================
Fan
"Richard Mueller" <rlmueller-NOSPAM@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:Oz7tc9J6GHA.4732@xxxxxxxxxxxxxxxxxxxxxxx
Hi,
There are two issues with lastLogon. First, the data type is Integer8,
which means it is a 64-bit (8-byte) number. This is too large for VB or
VBScript to handle. When you attempt to output the value you get the type
mismatch error. There are ways to handle Integer8 values, using the
IADsLargeInteger interface provided by ADSI (see links below).
The second issue is that the lastLogon attribute is not replicated. A
different value for each user is saved in the copy of AD on every Domain
Controller. This is to reduce the replication burden that would result if
this value had to replicate every time every user logged on. To get the
true lastLogon value for a user, you must query every Domain Controller
in the domain.
If you domain is at Windows 2003 functional level, you can use the new
lastLogonTimeStamp attribute. This is also Integer8, but is replicated.
However, the value is only updated during logon if the previous value is
more than 14 days in the past. This meets most needs, where you are
searching for unused accounts. The value retrieved is accurate within 14
days.
Here is a sample VBScript program that retrieves the lastLogon attribute
for all users in a domain:
http://www.rlmueller.net/Last%20Logon.htm
This program first uses ADO to retrieve the name of every DC in the
domain. Then it uses ADO to query every DC for the lastLogon attribute of
all users. It uses the IADsLargeInteger interface to convert the Integer8
values to dates. For each user the largest (latest) value is retained and
output at the end. I have some information on handling Integer8
attributes at this link:
http://www.rlmueller.net/Integer8Attributes.htm
Here is a Microsoft link explaining some of these issues with lastLogon
and lastLogonTimeStamp:
http://www.microsoft.com/technet/scriptcenter/topics/win2003/lastlogon.mspx
--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
"Fan" <bkhung@xxxxxxxxxxx> wrote in message
news:O9uQ2rJ6GHA.3452@xxxxxxxxxxxxxxxxxxxxxxx
hello,
I tried to get user information from the domain with vbs. The script
retrieved information such as the 'Name' field fine but it gave me error
when tyied to get information such as the user's 'LastLogon'. The error
message is "Type misMatch" at the excution of code: 'msgbox
oRS.Fields("LastLogon")'. I apprecate for any help on how to get the
'LastLogon' statement work in the vbscript that I included below: - Fan
'========== Sample script ===================
strBase = "<LDAP://dc=myDomain, dc=com>"
strFilter = "(&(objectCategory=person)(objectClass=user)(cn=Joe
Johnson))"
strAttributes = "name,LastLogon"
strFields = "name,LastLogon"
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False
Set oRS = objCommand.Execute
Do Until oRS.EOF
On error resume next
msgbox oRS.Fields("Name") 'Remark: this will display 'Joe
Johnson'
msgbox oRS.Fields("LastLogon") 'Remark: this will generate error
If Err then
msgbox Err.description 'Remark: displays: 'Type
mismatch'
Err.clear
End if
oRS.MoveNext
Loop
'=========== end script sample ==============
.
- Follow-Ups:
- Re: lastLogon
- From: Fan
- Re: lastLogon
- References:
- lastLogon
- From: Fan
- Re: lastLogon
- From: Richard Mueller
- Re: lastLogon
- From: Fan
- lastLogon
- Prev by Date: How to instantiate Server object in client script
- Next by Date: Re: Script to accept a dll name an return the file path from the registry
- Previous by thread: Re: lastLogon
- Next by thread: Re: lastLogon
- Index(es):