Re: lastLogon
- From: "Fan" <bkhung@xxxxxxxxxxx>
- Date: Fri, 6 Oct 2006 08:33:14 -0700
hi Richard,
Thank you for the reply and for the information. I will follow your advice
to work around the problem rather then sticking to one method.
Fan
"Richard Mueller" <rlmueller-NOSPAM@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:OduL0XO6GHA.4112@xxxxxxxxxxxxxxxxxxxxxxx
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 ==============
.
- References:
- lastLogon
- From: Fan
- Re: lastLogon
- From: Richard Mueller
- Re: lastLogon
- From: Fan
- Re: lastLogon
- From: Richard Mueller
- lastLogon
- Prev by Date: Re: ado connection.execute "syntax error"
- Next by Date: deposit a file on the clipboard
- Previous by thread: Re: lastLogon
- Next by thread: Error Handling
- Index(es):