AD acount getting locked every 5 minutes after password change.

We have password policy to change password every 90 days. Last week at the end of month, as usual, I got the message that my password is expiring and I must chang it. I changed my AD password to new one.  Within 5 min while I was trying to RDP to a server, I got a prompt that my account is locked. We have a Quest Password Manager tool where I can answer some security questions and unlock it. I unlocked my account. After 5-10 minutes I get that my password is locked again. I again unlock it. This went on for sometime.

I figured this started happening after I changed my password. This was because I have a RDP session connected to one of the servers where I have not logged off but have disconnected. We support around 1500 servers in that domain, and sometimes it just happens, for various reasons. This connection is retrying with my old password and in the process locking my account due to wrong password (old password). As per AD policy I can’t change my password to my last password.

I created a ticket for support and they said I have to wait till L3 can come and run scan to see where is this coming from. That will mean 10-12 hours of wait for them to come online, then some one will take up my case, run scan and will let me know, and this ceratinly was not a priority ticket as only one user was affected.

I started checking and found a blog from Alan Kaplan with a VB code:

Option Explicit    
dim wshShell
Set wshShell = WScript.CreateObject(“WScript.Shell”)
Dim retval
Dim oConn, oCmd, oRS
Dim strADSPath, strADOQuery
Dim strDomainCN
Dim fso,logfile, appendout
Dim strUser, strSessionID

‘Get the default ADsPath for the domain to search.
Dim root: Set root = GetObject(“LDAP://rootDSE”)
strADSPath = root.Get(“defaultNamingContext”)

Const ForAppend = 8
Set fso = CreateObject(“Scripting.FileSystemObject”)

If (Not IsCScript()) Then ‘If not CScript, re-run with cscript…
dim quote

WshShell.Run “CScript.exe ” & quote & WScript.ScriptFullName & quote, 1, true
    WScript.Quit            ‘…and stop running as WScript
End If

If InStr(1,MyOS,”Server”,1) = 0 Then
MsgBox “You must run this from server OS”,vbExclamation + vbOKOnly,”Error”
End If

retval = MsgBox(“This script will identify and optionally logoff disconnected sessions for a user on all of the servers ” & _
“in AD within a domain. Do you want to continue?”,vbYesNo + vbQuestion,”Get List of all Servers”)
If retval = vbNo Then WScript.Quit

strADSPath = InputBox(“Get server list from what domain”,”Domain”,strADSPath)
If strADSPath = “” Then WScript.Quit

strUser = InputBox(“Search for what username?”,”User Name”,wshShell.ExpandEnvironmentStrings(“%USERNAME%”))
If strUser = “” Then WScript.Quit

dim message
message = “Do you want to:” & VbCrLf & _
“1) Get list only” & VbCrLf & _
“2) Reset disconnected sessions” & VbCrLf & _
“3) Reset all sessions for user” & VbCrLf & _
“0) Quit”

Dim iActionType
iActionType  = InputBox(message,”Choose Action”,1)
iActionType = CDbl(iActionType)
If iActionType = 0 Then WScript.Quit

wshShell.Run “notepad.exe ” & quote & logfile & quote

‘ =========== Functions and Subs ==========

Sub GetServerList()

‘— Set up the connection —
Set oConn = CreateObject(“ADODB.Connection”)
Set oCmd = CReateObject(“ADODB.Command”)
oConn.Provider = “ADsDSOObject”
oConn.Open “ADs Provider”
Set oCmd.ActiveConnection = oConn
oCmd.Properties(“Page Size”) = 50
ocmd.Properties(“Chase referrals”) = ADS_CHASE_REFERRALS_ALWAYS

logfile = Replace(strADSPath,”,”,”_”)
logfile = Replace(logfile,”DC=”,””)
logfile = wshShell.ExpandEnvironmentStrings(“%userprofile%”) & “\desktop\” & strUser & ” In ” &  logfile & “.txt”

If fso.FileExists(logfile) Then fso.DeleteFile logfile,True
set AppendOut = fso.OpenTextFile(logfile, ForAppend, True)
strDomainCN = DomainCN(strADSPath)

‘— Build the query string —
strADOQuery = “<LDAP://” & strDomainCN & “/” & strADSPath & “>;” & “(&(OperatingSystem=*Server*)(objectClass=computer))” &  “;” & _
oCmd.CommandText = strADOQuery

‘— Execute the query for the object in the directory —
Set oRS = oCmd.Execute
If oRS.EOF and oRS.Bof Then
MsgBox  “No Servers AD entries found!”,vbCritical + vbOKOnly,”Failed”
appendout.WriteLine “Query Failed”
While Not oRS.Eof
   SessionQuery oRS.Fields(“Name”)
End If

End Sub

Sub SessionQuery (strServer)
WScript.Echo “Checking ” & strServer
dim objEx, data
Set objEx = WshShell.Exec(“QWinsta /server:” & strServer)
‘one line at a time
While Not (objEx.StdOut.AtEndOfStream)
data = objEx.StdOut.ReadLine
If InStr(1,data,strUser,1) Then
strSessionID = GetSession(data)
if iactionType = 1 then
EchoAndLog strServer & “,found session for ” & strServer
Wscript.echo strServer & “,found session for ” & strServer
End if
‘always logoff
If iActionType = 3 Then ResetSession strServer, strSessionID

‘Logoff disconnected
If iActionType =2 And InStr(1,data,”disc”,1) Then
ResetSession strServer,strSessionID
End If
End If
End Sub

Sub ResetSession(strServer, ID)
Dim strCommand, oExec
strCommand = “reset session ” & id & ” /server:”  & strServer
Set oExec    = WshShell.Exec(strCommand)
wscript.sleep 500

‘this is typically empty
While Not (oExec.StdOut.AtEndOfStream)
EchoAndLog oExec.StdOut.ReadLine

If oExec.ExitCode <> 0 Then
     EchoAndLog strServer & “,Problem resetting session ” & ID & ” on server ” & strServer & “, Non-zero exit code, ” & oExec.exitcode
EchoAndLog strServer & “,Reset session ” & ID & ” on server ” & strServer
End If
End Sub

Function DomainCN(strPath)
DomainCN = Replace(strPath,”,”,”.”)
DomainCN= Replace(DomainCN,”DC=”,””)
End Function

Function MyOS()
Dim oWMI,ColOS,ObjOS, OSver
Set oWMI = GetObject(“winmgmts:\\.\root\cimv2”)
Set ColOS = oWMI.ExecQuery(“SELECT Caption, version FROM Win32_OperatingSystem”)

For Each ObjOS In ColOS
MyOS = objOS.caption & Space(1) & objos.version
End Function

Function GetSession(text)
text = strip(lcase(Text))
Dim tArray, i

tArray = Split(text,Space(1))
i = 0
While tArray(i) <> lCase(strUser)
i = i +1

GetSession = tArray(i+1)
End Function

Function Strip(text)
text = Replace(text,vbtab,Space(1))
While InStr(text,Space(2)) > 0
text = replace(text,Space(2),Space(1))
Strip = text
End Function

Sub EchoAndLog (message)
‘Echo output and write to log
Wscript.Echo message
AppendOut.WriteLine message
End Sub 

Function IsCScript()
    If (InStr(UCase(WScript.FullName), “CSCRIPT”) <> 0) Then
        IsCScript = True
        IsCScript = False
    End If
End Function

Go to ‘Start’ and select ‘Run’, type NOTEPAD in the box and hit ‘Enter’. It will open a new text document. Paste the code above in to the file. Click on ‘File’ on the left top, select ‘Save As’. It will have *.TXT. Change it to Session.VBS (or any other name dot VBS) . Save it to Desktop or any other folder you want to.

Now just double click on the file to run it. It will prompt you with a message to continue. Click ‘Yes’ to continue. It will automatically pickup the domain info. Click ‘OK’. It will prompt you ‘Search for what User Name’. It will have your Username (Login Name).  You can change it to other user name if you are scanning for some one else. Click ‘OK’. Next option will be to choose ‘Action’.  Select 1 to list only.  You have options to ‘Reset disconnected sessions’ (2)  and ‘Reset all sessions’ (3).  I prefer just listing that is option 1. I do not want it disconnect my session where I may be working. I sometimes run scripts which run for 8-10 hours and I check on them next day on my next shift.  Click ‘OK’ after selecting your option.

It will create a text file in the same folder where the session.vbs file is located. It will scan all servers in the domain and will list servers where the user is connected and will reset it if that option is chosen.

For me it ran for around 8 hours and I got 2 servers where I had a disconnected session. I unlocked my account again and logged off my sessions from those two servers.

My account did not lock again as there were no sessions no more trying to connect with wrong/old password.

About: Niraj Kumar

Leave a Reply

Your email address will not be published. Required fields are marked *