Michael wrote:
> Our Help Desk has up until recently being stupidly creating all new user
> accounts with the same default password and NOT setting the flag to force
> a
> password change at first logon.
>
> Does anyone have a scriptlet that checks an AD user's password ?
>
> I want to run the script against all AD users to check which ones have the
> default
> password. One way to check if the password value matches the default is to attempt to
change it (using the ChangePassword method of the user object which requires
that you provide the existing password), but that is unacceptable. The only
other method I can think of is to attempt to bind to an object using
alternate credentials. For example:
===========
Const ADS_SECURE_AUTHENTICATION = &H1
strUser = "MyDomain\TestUser"
strUser = "cn=TestUser,ou=West,dc=MyDomain,dc=com"
strPassword = "zyx123q"
Set objNS = GetObject("LDAP:")
On Error Resume Next
Set objDomain = objNS.OpenDSObject("LDAP://dc=MyDomain,dc=com", strUser,
strPassword, ADS_SECURE_AUTHENTICATION)
If (Err.Number = 0) Then
On Error GoTo 0
Wscript.Echo "User " & strUser & " has default password"
Else
On Error GoTo 0
Wscript.Echo "User " & strUser & " is OK"
End If
========
The user name can be in either of the forms shown above. To runs similar
code against every user in the domain will be slow, but you could use ADO to
retrieve all user DN's. For example (not tested):
========
Option Explicit
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset
Dim strUser, strPassword, objNS, strUser, strPassword, objDomain
Const ADS_SECURE_AUTHENTICATION = &H1
Set objNS = GetObject("LDAP:")
' Specify the default password to be checked.
strPassword = "password"
' Setup ADO objects.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
' Search entire Active Directory domain.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = "<LDAP://" & strDNSDomain & ">"
' Filter on user objects.
strFilter = "(&(objectCategory=person)(objectClass=user))"
' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName"
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
' Run the query.
Set adoRecordset = adoCommand.Execute
' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve user DN.
strUser = adoRecordset.Fields("distinguishedName").Value
' Attempt to bind to domain object with alternate credentials.
' Trap the error if the attempt fails.
On Error Resume Next
Set objDomain = objNS.OpenDSObject("LDAP://" & strDNSDomain, _
strUser, strPassword, ADS_SECURE_AUTHENTICATION)
If (Err.Number = 0) Then
On Error GoTo 0
Wscript.Echo "User " & strUser & " has default password"
End If
On Error GoTo 0
' Move to the next record in the recordset.
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
========
This script should be run at a command prompt with the cscript host. It will
echo the DN of all users with the default password as specified in the
script. You could redirect the output to a text file. This could take
awhile, as it must bind to every user object in the domain. You could
restrict the program to one OU by specifying the AdsPath of the OU as the
base of the query (the value of the variable strBase). You could then expire
the password for the users found to still be using the default.
--
Richard Mueller
MVP Directory Services
Hilltop Lab -
http://www.rlmueller.net
--