Hi,
Nice work - and big thanks to previous posters as the previous scripts gave me a little inspiration.
The only problem I had with the previous versions of the script was that it took a long time to run for me. This is because it enumerates every object in the domain and that can take time.
This lead me to making a modified version which uses an LDAP query to only pull locked accounts which are also enabled. I've included the script below.
The script takes a single mandatory parameter which is the domain to check in DNS format (i.e. contoso.com, uk.contoso.com etc.). If you wish you can also save the script as a regular .vbs file and adding /view onto the end of the parameters will also show the list of locked accounts.
Example syntax:
Just show the count: cScript.exe ScriptName.vbs contoso.com
Show the list too: cScript.Exe ScriptName.vbs contoso.com /view
Code: Select all
Option Explicit
'Define required variables
Dim objConnection
Dim iX
Dim objCommand
Dim objRecordSet
Dim sRetVal
Dim arrAttribute
Dim iDaysSinceDisabled
Dim iCount
Dim sDomain
Dim bListAccounts
Dim arrAccounts
'Define constants
const statusAlive = "scriptRes:Host is alive:"
const statusDead = "scriptRes:No answer:"
const statusUnknown = "scriptRes:Unknown:"
const statusNotResolved = "scriptRes:Unknown host:"
const statusOk = "scriptRes:Ok:"
const statusBad = "scriptRes:Bad:"
const statusBadContents = "scriptRes:Bad contents:"
'Initialise the array
Redim arrAccounts(2,0)
'Get the parameters
sDomain = wScript.Arguments(0)
sDomain = GetNCFromDNSDomain(sDomain)
'If there are more parameters then...
If wScript.Arguments.Count >=2 Then
'If the second argument is /view
If LCase(wScript.Arguments(1)) = "/view" Then bListAccounts = True
End If
'Define required constants
Const ADS_SCOPE_SUBTREE = 2
Const ADS_CHASE_REFERRALS_ALWAYS = &H60
'Make the objects and configure them
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
'Define the query and load into the command object
Set objCommand.ActiveConnection = objConnection
'Query the appropriate OU for objects that are still disabled; this is deliberate to stop accounts which have been re-enabled but not moved from being deleted
objCommand.CommandText = "<LDAP://" & sDomain & ">;(&(objectCategory=Person)(objectClass=User)(lockoutTime>=1)(!userAccountControl:1.2.840.113556.1.4.803:=2));samAccountName,Name;Subtree"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Chase Referrals") =&H60
'Run the query
Set objRecordSet = objCommand.Execute
'Loop through the results
Do While Not objRecordSet.EOF
'If the option to list was given then load values into the array
If bListAccounts Then
arrAccounts(0,UBound(arrAccounts,2)) = objRecordset.Fields(0)
arrAccounts(1,UBound(arrAccounts,2)) = objRecordset.Fields(1)
arrAccounts(2,UBound(arrAccounts,2)) = objRecordset.Fields(2)
Redim Preserve arrAccounts(2,UBound(arrAccounts,2)+1)
End If
'Increment the counter
iCount = iCount+ 1
'Move to the next record
objRecordset.MoveNext
Loop
'Display the results
wScript.StdOut.Write statusOk & iCount
'If the option to view the locked accounts was given then...
If bListAccounts Then
wScript.Echo ""
wScript.Echo "SAM Account Name Name"
For iX=0 To UBound(arrAccounts,2)
wScript.Echo PadString(arrAccounts(0,iX),25) & arrAccounts(1,iX)
Next
End If
'End the script
wScript.Quit
Function GetNCFromDNSDomain(sDNSDomain)
'Define required variables
Dim sRetVal
Dim arrParts
Dim objItem
'If there are periods in the string then...
If Instr(sDNSDomain,".") > 0 Then
'Split by the full stops
arrParts = Split(sDNSDomain,".")
'Loop through and build the string
For Each objItem In arrParts
sRetVal = sRetVal & "dc=" & objItem & ","
Next
'Strip the final ,
sRetVal = Left(sRetVal,Len(sRetVal)-1)
End If
'Return the value
GetNCFromDNSDomain = sRetVal
End Function
Function PadString(sString,iLen)
'Define required variables
Dim sRetVal
'If the length is less than needed then pad with spaces
If Len(sString) < iLen Then
sRetVal = sString & String(iLen-Len(sString)," ")
Else
'If it's too long then chop it
If Len(sString) > iLen Then
sRetVal = Left(sString,iLen)
Else
'Otherwise just pass it back
sRetVal = sString
End If
End If
'Return the value
PadString = sRetVal
End Function