Table of Content > Extended Handling of AD Objects > LDAP Search Factory > How to find disabled user accounts in Active Directory
How to search and find disabled user accounts in Active Directory
We use the Active Directory attribute userAccountControl for this LDAP search. For disbled user accounts the flag bit UF_ACCOUNT_DISABLE (2) is set. The SelfADSI tutorial article about LDAP filters shows in detail how to search for single flags in such bit fields. For the general explanation of LDAP searches read the SelfADSI chapter 'Searching LDAP objects in the directory'.
Finding all disabled users in the own domain
This script finds all the disabled user accounts in the domain in which the current user is a member of:
ldapFilter = "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=2))"
Set rootDSE = GetObject("LDAP://rootDSE")
domainDN = rootDSE.Get("defaultNamingContext")
Set ado = CreateObject("ADODB.Connection")
ado.Provider = "ADSDSOObject"
ado.Open "ADSearch"
Set objectList = ado.Execute("<LDAP://" & domainDN & ">;" & ldapFilter & _
";distinguishedName,samAccountName,displayname,userPrincipalName;subtree")
While Not objectList.EOF
userDN = objectList.Fields("distinguishedName")
logonName = objectList.Fields("samAccountName")
On Error Resume Next
displayName = "" : displayName = objectList.Fields("displayname")
logonNameUPN = "" : logonNameUPN = objectList.Fields("userPrincipalName")
On Error Goto 0
WScript.Echo logonName & ";" & logonNameUPN & ";" & displayName & ";" & userDN
objectList.MoveNext
Wend
Some notes according to this script:
The LDAP filter which is used here to find user acounts in general is (samAccountType=805306368). Note that this is more efficient and faster than the filter (&(objectCategory=person)(objectClass=user)) which is used more often.
When we want to read the attributes, there is a trick used to prevent runtime errors in case of non existing values. First we set the variable to an empty string, then we try to read the attribute value - the runtime error handling is deactivated for these commands. We don't need this for attributes which are always there. The separating colon (:) is used to execute the two VBScript commands in the same line:
...
On Error Resume Next
displayName = "" : displayName = objectList.Fields("displayname")
On Error Goto 0
Finding all disabled users in any domain / OU
This script finds all disabled user accounts in the specified domain or OU. Use the suitable LDAP path for your desired domain or container. You could set also other credentials for the search (username and password specified):
searchDN = "DC=example,DC=com" 'insert your own search base container or domain name
serverName = "192.168.0.66" 'insert your own DC's name or address
userName = InputBox("Enter user name","Credentials") 'you could also just use a static username instead, like "EXAMPLE\userXYZ"
password = InputBox("Enter password","Credentials") 'you could also just use a static password instead, like "P@ssw0rd"
ldapFilter = "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=2))"
Set ado = CreateObject("ADODB.Connection")
ado.Provider = "ADSDSOObject"
ado.Properties("User ID") = userName
ado.Properties("Password") = password
ado.Properties("Encrypt Password") = True
ado.Open "ADSearch"
Set objectList = ado.Execute("<LDAP://" & serverName & "/" & searchDN & ">;" & ldapFilter & _
";distinguishedName,samAccountName,displayname,userPrincipalName;subtree")
While Not objectList.EOF
userDN = objectList.Fields("distinguishedName")
logonName = objectList.Fields("samAccountName")
On Error Resume Next
displayName = "" : displayName = objectList.Fields("displayname")
logonNameUPN = "" : logonNameUPN = objectList.Fields("userPrincipalName")
On Error Goto 0
WScript.Echo logonName & ";" & logonNameUPN & ";" & displayName & ";" & userDN
objectList.MoveNext
Wend