Automatically disable inactive logon accounts in active directory

If you are administering a large domain  I am sure you have the headache of trying to keep user accounts current. people come and people go and the network admin is usually the last person any one tells. Unfortunately that leaves a serious security vulnerability for you to deal with. possible high level accounts just hanging out in limbo. Hopefully you have a the auto password change configured on you domain but to go one step further it is always wise to run a script to find the accounts that have not logged on and disable them.

you can use the following VBS code to do this all for you

I found this code ON a technet site unfortunatly it was incomplete. I added the finishing touches to get it fully functional.

just modify the variables settings to match your AD. good luck and stay secure.

 

'===========================================================================
' Checks all accounts to determine what needs to be disabled.
' If LastLogonTimeStamp is Null and object is older than specified date, it is disabled and moved.
' If account has been used, but not within duration specified, it is disabled and moved.
' If account is already disabled it is left where it is.
' Created 23/7/09 by Grant Brunton
'===========================================================================

'===========================================================================
' BEGIN USER VARIABLES
'===========================================================================

' Flag to enable the disabling and moving of unused accounts
' 1 - Will Disable and move accounts
' 0 - Will create ouput log only
bDisable=0

' Number of days before an account is deemed inactive
' Accounts that haven't been logged in for this amount of days are selected
iLogonDays=60

'Active directory root
'eg:  "OU=yourdomain,dc=org"
DSERoot="dc=yourdomain,dc=org"

' LDAP Location of OUs to search for accounts
' LDAP location format eg: "ou=users,ou=users"
strSearchOU="ou=users,ou=users"

' Search depth to find users
' Use "OneLevel" for the specified OU only or "Subtree" to search all child OUs as well.
strSearchDepth="OneLevel"

' Location of new OU to move disabled user accounts to
' eg: "OU=Disabled Users,OU=Test"
strNewOU="ou=disabled accounts,ou=users"

' Log file path (include trailing \ )
' Use either full directory path or relational to script directory
strLogPath=".\logs\Accountdisablelog\"

' Error log file name prefix (tab delimited text file. Name will be appended with date and .err extension)
strErrorLog="DisabledAccounts_"

' Output log file name prefix (tab delimited text file. Name will be appended with date and .log extension)
strOutputLog="DisabledAccounts_"

'===========================================================================
' END USER VARIABLES
'===========================================================================


'===========================================================================
' MAIN CODE BEGINS
'===========================================================================
sDate = Year(Now()) & Right("0" & Month(Now()), 2) & Right("0" & Day(Now()), 2) 
Set oFSO=CreateObject("Scripting.FileSystemObject")
If Not oFSO.FolderExists(strLogPath) Then CreateFolder(strLogPath)
Set output=oFSO.CreateTextFile(strLogPath & strOutputLog & sDate & ".log")
Set errlog=oFSO.CreateTextFile(strLogPath & strErrorLog & sDate & ".err")
output.WriteLine "Sam Account Name" &vbTab& "LDAP Path" &vbTab& "Last Logon Date" &vbTab& "Date Created" &vbTab& "Home Directory"
errlog.WriteLine "Sam Account Name" &vbTab& "LDAP Path" &vbTab& "Problem" &vbTab& "Error"

Set rootDSE = GetObject("LDAP://rootDSE")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider=ADsDSOObject;"
Set ObjCommand = CreateObject("ADODB.Command")
ObjCommand.ActiveConnection = objConnection
ObjCommand.Properties("Page Size") = 10
DSEroot=rootDSE.Get("DefaultNamingContext")

Set objNewOU = GetObject("LDAP://" & strNewOU & "," & DSEroot)
ObjCommand.CommandText = ";(&(objectClass=User)(objectcategory=Person));adspath;" & strSearchDepth

Set objRecordset = ObjCommand.Execute

On Error Resume Next

While Not objRecordset.EOF
	LastLogon = Null
	intLogonTime = Null

	Set objUser=GetObject(objRecordset.fields("adspath"))

	If DateDiff("d",objUser.WhenCreated,Now) > iLogonDays Then
		Set objLogon=objUser.Get("lastlogontimestamp")
		If Err.Number <> 0 Then
			WriteError objUser, "Get LastLogon Failed"
			DisableAccount objUser, "Never"
		Else
			intLogonTime = objLogon.HighPart * (2^32) + objLogon.LowPart
			intLogonTime = intLogonTime / (60 * 10000000)
			intLogonTime = intLogonTime / 1440
			LastLogon=intLogonTime+#1/1/1601#

			If DateDiff("d",LastLogon,Now) > iLogonDays Then
				DisableAccount objUser, LastLogon
			End If
		End If
	End If
	WriteError objUser, "Unknown Error"
	objRecordset.MoveNext
Wend
'===========================================================================
' MAIN CODE ENDS
'===========================================================================


'===========================================================================
' SUBROUTINES
'===========================================================================
Sub CreateFolder( strPath )
	If Not oFSO.FolderExists( oFSO.GetParentFolderName(strPath) ) Then Call CreateFolder( oFSO.GetParentFolderName(strPath) )
	oFSO.CreateFolder( strPath )
End Sub

Sub DisableAccount( objUser, lastLogon )
	On Error Resume Next
	If bDisable <> 0 Then
		If objUser.accountdisabled=False Then
			objUser.accountdisabled=True
			objUser.SetInfo
			WriteError objUser, "Disable Account Failed"
			objNewOU.MoveHere objUser.adspath, "CN="&objUser.CN
			WriteError objUser, "Account Move Failed"
		Else
			Err.Raise 1,,"Account already disabled. User not moved."
			WriteError objUser, "Disable Account Failed"
		End If
	End If
	output.WriteLine objUser.samaccountname &vbTab& objUser.adspath &vbTab& lastLogon &vbTab& objUser.whencreated &vbTab& objUser.homedirectory
End Sub

Sub WriteError( objUser, strProblem )
	If Err.Number <> 0 Then
		errlog.WriteLine objUser.samaccountname &vbTab& objUser.adspath &vbTab& strProblem &vbTab& Replace(Err.Description,vbCrlf,"")
		Err.Clear
	End If
End Sub

'===========================================================================
' END SUBROUTINES
'===========================================================================