Domain user Last-logon-Timestamp not get updated from DC and ADC.

Posted on 2009-12-27
Medium Priority
Last Modified: 2012-05-08
Last-logon-Timestamp not get updated from DC and ADC.
need command to sync the same.
Question by:mash1978

Author Comment

ID: 26129231

Time on DC and ADC are same no difference.

i want to disable unused accounts and if users Last-logon-Timestamp are different in DC and ADC
in active directory user account information . if script run on Dc and new user last logged on ADC then it's account get disable.
LVL 81

Expert Comment

ID: 26131123
run dcdiag and netdiag to make sure there are no sync/replication problems.
Check the event logs on both for clues as well.
Alternatively, you can setup a GPO with a login/logout script that applies to all user that records their login/logout events.

A similar script can be used for the logout script.

You could use a VBS script and do the same thing inserting the data into an SQL database.
@echo off
echo %DATE% %TIME% %USERNAME% Loggged in %COMPUTERNAME% %SESSIONNAME% >> \\someshareserver\sharename\recordfile.txt

Open in new window

LVL 31

Expert Comment

by:Henrik Johansson
ID: 26173403
This is expected as the last logon attribute is a information about when user last authenticated with the specific DC, and this information isn't replicated between the DCs.
If you want the actual last logon timestamp when having multiple DCs, you nead to check each DC as the information will not be replicated.
Instead of connecting to each DC, it's preferably done with a script.

So, your thaught about disable the user on a criteria with different logon timestamp on different DC wouldn't be a good idea.

As you want to find inactive users, use dsquery (MS standard tool in adminpak.msi) or adfind (http://www.joeware.net/freetools/tools/adfind/index.htm), you can query for inactive users

To query domain for all users that has been inactive for 5 weeks by using dsquery:
dsquery user -inactive 5 -limit 0

If you want to automate the disabling, you can pipe the result to dsmod
dsquery user -inactive 5 -limit 0 | dsmod user -inactive yes
Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  


Author Comment

ID: 26756204
To query domain for all users that has been inactive for 5 weeks by using dsquery:
dsquery user -inactive 5 -limit 0

If you want to automate the disabling, you can pipe the result to dsmod
dsquery user -inactive 5 -limit 0 | dsmod user -inactive yes

Above commands will search for users last logon attribute on both DC and ADC or only any of one.
LVL 15

Accepted Solution

markdmac earned 600 total points
ID: 26849924
Here you go, this script will disable accounts that have not logged on for more than 60 days.  Just search for "60" to change the number of idle days if you need to alter that time frame.
' NAME: Disable60DayIdle.vbs
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: http://www.thespidersparlor.com
' DATE  : 11/18/2004
' COMMENT: Determines when each user in the domain last logged on
'          Disables accounts inactive for 60 days or more
'          Thanks to Richard Mueller for sample code to query DCs.
' 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.

Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, objList, strUser, IdleAge
Dim strBase, strFilter, strAttributes, lngHigh, lngLow
Dim outfile, Report, fso, ts, ForWriting

IdleAge = "60"

' 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)
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 = _
  ReDim Preserve arrstrDCs(k)
  arrstrDCs(k) = objDC.DNSHostName
  k = k + 1

' 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)
    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#
        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#
          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
        objList.Add strDN, dtmDate
      End If
  End If

For Each strUser In objList
	lnameArray = split(strUser,",")
	nameLength = Len(lnameArray(0)) - 3
	lname = Right(lnameArray(0),nameLength)
	Select Case LCase(lname)
	      'Add additional accounts to ignore here
		  Case "guest","krbtgt","administrator"
		  		'Do Nothing
		  Case Else
		    If DateDiff("d",objList(strUser), Now()) >= CInt(IdleAge) Then
		      ' Now Disable the account, remove group memberships and move the account
			End If
		End Select
' Clean up.
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing

Function DisableUser(userDN)
	On Error Resume Next
	Dim oRootDSE, oConnection, objCommand, ldstring, oRecordset, disUser, newDescription
	Const E_ADS_PROPERTY_NOT_FOUND  = &h8000500D
	Set oRootDSE = GetObject("LDAP://rootDSE")
	DisOUstr = "LDAP://OU=Disabled Users,OU=Users,OU=Parsippany," & oRootDSE.get("defaultNamingContext")
	Set objOU = GetObject(DisOUstr)
	Set objUser = GetObject("LDAP://" & userDN)
	newDescription = "TERM - DEL on " & Date()+30
	'update the user description
	objUser.Put "description", newDescription
	'Now remove group memberships
	arrMemberOf = objUser.GetEx("memberOf")
		    'This account is not a member of any security groups.
			For Each Group in arrMemberOf
				Set objGroup = GetObject("LDAP://" & Group) 
			    objGroup.PutEx ADS_PROPERTY_DELETE, _
			        "member", Array(userDN)
	End If
	'Hide from the GAL
	objUser.Put "msExchHideFromAddressLists", True
	'Now disable the account
	intUAC = objUser.Get("userAccountControl")
	objUser.Put "userAccountControl", intUAC OR ADS_UF_ACCOUNTDISABLE
	'Move the account
	objOU.MoveHere objUser.ADsPath, objUser.Name

End Function

Open in new window


Author Comment

ID: 27199643
Good , Thanks

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

So you have two Windows Servers and you have a directory/folder/files on one that you'd like to mirror to the other?  You don't really want to deal with DFS or a 3rd party solution like Doubletake. You can use Robocopy from the Windows Server 200…
On July 14th 2015, Windows Server 2003 will become End of Support, leaving hundreds of thousands of servers around the world that still run this 12 year old operating system vulnerable and potentially out of compliance in many organisations around t…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question