Photo Gallery Member List Search Calendars FAQ Ticket List Log Out


"Last Logon" script for Active Directory AND Exchange 2000

 
Logged in as: Guest
arrSession:exec spGetSession 2,2,24625
 Active Users: There are 0 members and 0 guests.
 Users viewing this topic: none
 

 

 
  
  Printable Version
All Forums >> [Scripting] >> WSH & Client Side VBScript >> "Last Logon" script for Active Directory AND Exchange 2000
  Do you like VisualBasicScript.com? Link to us and help spread the word about our forum. Thanks!
Page: [1]
Login
Message << Older Topic   Newer Topic >>
 "Last Logon" script for Active Directory AND ... - 8/9/2005 12:44:29 PM   
  colbytrio

 

Posts: 27
Score: 1
Joined: 4/8/2005
From:
Status: offline
I have been looking all over the internet for a solution to this problem and have had no luck.  Hopefully someone here can help me out.
 
My organization has close to 10,000 user objects in Active Directory and close to 5,000 mail boxes in Exchange 2000.  I have been assigned the task of cleaning up Active Directory by removing all the stale and inactive accounts.  In preparation to this task we have upgraded all 60 our Domain Controllers to Windows 2003.  And just recently (within the last week) we have raised the Domain Function level to Windows 2003.
 
Once we upgraded the domain level the DC's began replicating the lastlogintimestamp attribute between the sites but it only shows the last login information AFTER the date we raised the domain level.  This is an issue because we were counting on this attribute to help us clean up the inactive Active Directory accounts.
 
So heres my question: Is there a script that can be ran that will tell me the last time a user has logged into both Active Directory AND Exchange?  **The reason why we need to know when a user last checked their e-mail is because we have several sites that use Macintosh computers along with Windows 9x clients (some log into the domain and some do not).**
 
Thanks in advance!
 
 
Post #: 1
 
 RE: "Last Logon" script for Active Directory ... - 8/10/2005 1:31:38 AM   
  colbytrio

 

Posts: 27
Score: 1
Joined: 4/8/2005
From:
Status: offline
Anyone...?

(in reply to colbytrio)
 
 
Post #: 2
 
 RE: "Last Logon" script for Active Directory ... - 8/10/2005 8:21:14 AM   
  Thenewguy

 

Posts: 3
Score: 0
Joined: 8/10/2005
Status: offline
I can't really help you with the Exchange scripting, but here is what I used to find "TRUE" last logon..and a major chunk of this was from rmueller's site...this uses the lastlogin field, not the lastlogontimestamp, so it connects to all your dc's and checks to see which stamp is newer.  Not sure if this information got updated when you elevated your domain's functional level or not...

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

'function to determine if account is disabled or not
'returns boolean value of true if the account is disabled, false if it is not
Function IsAccountDisabled( strDomain, strAccount )
   Dim objUser
   Set objUser = GetObject("WinNT://" & strDomain & "/" & strAccount & ",user")
   IsAccountDisabled = objUser.AccountDisabled
End Function


' Create dictionary to keep track of
' users and login times
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare
' rmueller's script
' 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))"
'added sAMAccount name for readability in output - el
strAttributes = "distinguishedName,lastLogon,sAMAccountName,"
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("sAMAccountName")
     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
       'stored as a 64 bit integer that VBScript cannot handle, must
       'seperate it to work with it.
       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
Dim objNetwork,objExcel
dim intRow
intRow = 2
Set objNetwork = Wscript.CreateObject("Wscript.Network")
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.Workbooks.Add

objExcel.Cells(1,1).value = "UserName"
objExcel.Cells(1,2).value = "Last Login"
objExcel.Cells(1,3).value = "Disabled"

' Output latest lastLogon date for each user.
Dim easydate, iDiff,strDays
strDays = InputBox("Enter number of days: ","Last Login", "60")
strDays = CInt(strDays)
For Each strUser In objList
'get rid of the timestamp, only need the date
easydate = objList(strUser)
easydate = FormatDateTime(easydate,2)
'calculate the difference between last login date
'and now.
iDiff = DateDiff("d",easydate,Now)

' check to see if account has been inactive for x number of days
If iDiff >= strDays Then

'output username and last login date
' change 1/1/1601 to Never because it looks nicer
If easydate = "1/1/1601" Then
 easydate = "Never"
End If 
'Else WScript.Echo strUser & " ; " & easydate
'End If
objExcel.Cells(intRow,1).value = strUser
objExcel.Cells(intRow,2).value = easydate

'populated disabled column
'if IsAccountDisabled("LSMASTER",strUser) Then
 objExcel.Cells(intRow,3).value = "DISABLED"' End if
intRow = intRow + 1
End If

Next

'sort by login Date
Dim obrange, obrange2
Set obrange = objExcel.Range("A:K")
Set obrange2 = objExcel.Range("B2")
obrange.Sort obrange2,1,,,,,,1


' 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
Set obrange = Nothing
Set obrange2 = Nothing
Set objExcel = Nothing
WScript.Quit





_____________________________

I'll put a sig in later, i swear

(in reply to colbytrio)
 
 
Post #: 3
 
 RE: "Last Logon" script for Active Directory ... - 8/10/2005 8:45:41 AM  1 votes
  colbytrio

 

Posts: 27
Score: 1
Joined: 4/8/2005
From:
Status: offline
Thanks for the first part of this crazy request!

One thing I forgot to mention, the Macs and Win9x machines use OWA to check e-mail. SO maybe I need a script that can look into Exchange to determine the last login for a mail box?

(in reply to colbytrio)
 
 
Post #: 4
 
 RE: "Last Logon" script for Active Directory ... - 12/11/2005 11:28:36 PM   
  Adele123

 

Posts: 2
Score: 0
Joined: 12/11/2005
Status: offline
Hi Thenewguy,

Script works fine. However I need to ignore disabled user accounts and list only current accounts.

Thanks

(in reply to Thenewguy)
 
 
Post #: 5
 
 RE: "Last Logon" script for Active Directory ... - 11/8/2006 5:07:07 PM   
  SAPIENScripter


Posts: 270
Score: 2
Joined: 11/1/2006
From: SAPIEN Technologies
Status: offline
The lastlogin attribute is not replicated between domain controllers unless you are running Windows 2003 native mode. You have to query all domain controllers and massage the information to get that information. I don't think an OWA authentication counts as a login.

If the script basically works then just add code to only list the user if the account is enabled.

_____________________________

Jeffery Hicks
Windows PowerShell MVP
SAPIEN Technologies - Scripting, Simplified. www.SAPIEN.com

Follow Me: http://www.twitter.com/JeffHicks

(in reply to Rob BL)
 
 
Post #: 6
 
 RE: "Last Logon" script for Active Directory ... - 3/27/2007 4:58:18 AM   
  sjhannon

 

Posts: 3
Score: 0
Joined: 8/9/2005
Status: offline
Forgive my newness to scripting...

in using this script, i noticed that regardless of wether or not the account was disabled, it reported the account as disabled.  In taking a closer look , i realized that the line "  'if IsAccountDisabled("LSMASTER",strUser) Then " is commented out.  apon uncommenting it , it kills the script. I either get an unexpected next , which i tried adding in the missing "end if" and the script runs , but then when the excel spreadsheet opens , it gets a timeout error when it attempts to write the first lines disabled status. I have tried various changes to the following section :

'populated disabled column
'if IsAccountDisabled("LSMASTER",strUser) Then
 objExcel.Cells(intRow,3).value = "DISABLED"' End if
intRow = intRow + 1
End If

Next

among the things i tried was the following :

If( IsAccountDisabled( "LSMASTER", strUser ) = True ) Then
objExcel.Cells(intRow,3).value = "DISABLED"
Else
objExcel.Cells(intRow,3).value = "Enabled"
intRow = intRow + 1
End If
End If

Next


Which i thought would work. I still get the timeout error.  ( and i tried extending the timeout value from 60 to 600 , but i get the same error still.)

I have a feeling it might have something to do with the "LSMASTER"..... as i have no idea what this is and couldnt find it listed in this script , on this site , or on google.

Outside of the accurate reporting of the account disabled function , this script works great. 

Can someone show me how to get that part working correctly

Thanks in advance

(in reply to colbytrio)
 
 
Post #: 7
 
 RE: "Last Logon" script for Active Directory ... - 3/30/2007 4:49:54 AM   
  sjhannon

 

Posts: 3
Score: 0
Joined: 8/9/2005
Status: offline
anyone?

(in reply to colbytrio)
 
 
Post #: 8
 
 RE: "Last Logon" script for Active Directory ... - 4/2/2007 5:26:16 AM   
  ebgreen


Posts: 4613
Score: 31
Joined: 7/12/2005
Status: offline
The first parameter of the IsDisabled function is the domain that the account is in. You would need to be sure that you are using a valid Domain.

_____________________________

"... when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick
Goog places to start:http://www.visualbasicscript.com/m_24727/tm.htm
http://www.visualbasicscript.com/m_47117/tm.htm

(in reply to sjhannon)
 
 
Post #: 9
 
 RE: "Last Logon" script for Active Directory ... - 4/10/2007 2:19:01 AM   
  sjhannon

 

Posts: 3
Score: 0
Joined: 8/9/2005
Status: offline
That did it.  Thanks so much ...probably should have figured that one out on my own ...  

(in reply to ebgreen)
 
 
Post #: 10
 
 RE: "Last Logon" script for Active Directory ... - 7/3/2007 12:34:20 AM   
  jtp755

 

Posts: 2
Score: 0
Joined: 7/3/2007
Status: offline
i know this thread is old but i must be missing something...i uncommented the mentioned line and changed LSMASTER to my domain and the script still wont work....what am i missing? thanks

(in reply to sjhannon)
 
 
Post #: 11
 
 RE: "Last Logon" script for Active Directory ... - 7/3/2007 2:54:55 AM   
  jtp755

 

Posts: 2
Score: 0
Joined: 7/3/2007
Status: offline
nevermind...i fixed it

(in reply to jtp755)
 
 
Post #: 12
 
 
 
  

If you found our site useful please link to us <a href="http://www.visualbasicscript.com">VisualBasicScript.com</a>.
All Forums >> [Scripting] >> WSH & Client Side VBScript >> "Last Logon" script for Active Directory AND Exchange 2000 Page: [1]
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts