Re: HELP! Need AD Query for Last login
- From: "Richard Mueller [MVP]" <rlmueller-NOSPAM@xxxxxxxxxxxxxxxxxxxx>
- Date: Mon, 4 Jul 2005 10:50:29 -0500
Hi,
To restrict the query to one domain, you need to modify the "base" of the
search. You want to do this only for the second query that runs on each DC.
As written, the variable strBase is defined by the statement:
strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
where strDNSDomain is the DNS name of the domain (retrieved from the rootDSE
object). For your purpose, redefine strDNSDomain to be the Distinguished
Name of the specific OU. For example:
strDNSDomain = "ou=Sales,ou=West,dc=MyDomain,dc=com"
Unfortunately, you still must query all DC's, as users could have logged in
from anywhere and been authenticated by any DC. Finally, if your domain is
at Windows 2003 functional level, you can query a single DC for the new
attribute lastLogonTimeStamp. This attribute is replicated, although it is
only updated if at least a week has passed since the last update.
If the original script ran to completion, I'd like to know how long it took,
and how long the revised script (restricting the query to one OU) took. From
experience, performance depends on the number of remote sites and the speed
of the links. Even though the number of users may be much less, the revised
script may not be much faster. Still, some people have been very happy that
the program finished in an hour, as they had no better alternative.
--
Richard
Microsoft MVP Scripting and ADSI
Hilltop Lab web site - http://www.rlmueller.net
--
"LOST" <LOST@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:760761F5-701B-45BC-9EF4-847D75B7C223@xxxxxxxxxxxxxxxx
> Hi all:
>
> I am stuck: I need to query a specific OU in a large AD Structure (over
> 100K user hence why a specifc OU) I need to determine and then export to a
> text or excel file all of the users in the OU that have a last login in
date
> more then 30 days. Now I have read that the last login is not replicated
to
> all DCs and that one will have to check all DCs for the last login date. I
> found a script listed below that will automaticly query the domain and
find
> all of the DCs and then list all of the users that have not logged in for
a
> long time, but it will only run on the entire domain hence it has to check
> all 100K user on each DC and then compare them and it takes for ever! Can
> anyone par it down so that it still querys the Domain for all of the DCs
and
> then determine the last login date over 30 days for a certian OU? Thanks
>
>
> ' Copyright (c) 2002 Richard L. Mueller royalty-free right to use
> ' 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.
> '
> ' 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
>
> ' 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
>
> ' 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))"
> strAttributes = "distinguishedName,lastLogon"
> 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
> strDN = objRecordSet.Fields("distinguishedName")
> lngDate = objRecordSet.Fields("lastLogon")
> 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(strDN) Then
> If dtmDate > objList(strDN) Then
> objList(strDN) = dtmDate
> End If
> Else
> objList.Add strDN, 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
>
.
- Follow-Ups:
- Re: HELP! Need AD Query for Last login
- From: Drew
- Re: HELP! Need AD Query for Last login
- From: LOST
- Re: HELP! Need AD Query for Last login
- References:
- HELP! Need AD Query for Last login
- From: LOST
- HELP! Need AD Query for Last login
- Prev by Date: HELP! Need AD Query for Last login
- Next by Date: Dynamic variable
- Previous by thread: HELP! Need AD Query for Last login
- Next by thread: Re: HELP! Need AD Query for Last login
- Index(es):
Relevant Pages
|
Loading