How Can I Verify that None of My Local User Accounts have a Blank Password?
Hey, Scripting Guy! How can I verify that none of my local user accounts have a blank password?
Hey, TB. To begin with, we should point out that at least some of you won’t need to make this check on computers within your domain; that’s because you’re using password policies in the domain that would prohibit the use of a blank password. (For example, you might require passwords to be at least 7 characters long, a policy that prevents anyone from using a blank password.) For organizations who don’t have a password policy (or for workgroups or home computers), however, you can use a script like this to check for blank passwords:
On Error Resume Next
Set objNetwork = CreateObject(“Wscript.Network”) strComputer = objNetwork.ComputerName
strPassword = “”
Set colAccounts = GetObject(“WinNT://” & strComputer) colAccounts.Filter = Array(“user”)
For Each objUser In colAccounts objUser.ChangePassword strPassword, strPassword If Err = 0 or Err = -2147023569 Then Wscript.Echo objUser.Name & ” is using a blank password.” End If Err.Clear Next
Admittedly, some of you might be looking at this and thinking, “That’s a nice little script and all. But how come you didn’t just run some sort of query asking for a list of users who have a blank password?” Well, there’s a good reason for that: there’s no way to run such a query. Even as administrators it’s impossible for us to write a script that retrieves a user’s password; there’s no way to get that information.
Therefore, we have to be a bit sneaky about this. What we do, instead, is try to change the user’s password using the ChangePassword method. ChangePassword requires us to know the user’s current password; in this script, we’ll try using a blank password as the user’s current password. If the script fails, that means the user is not using a blank password. If the script succeeds, however, that can only mean one thing: the user is using a blank password. In that case, we’ll echo back the name of that user.
To do this we start out by adding the On Error Resume Next statement, creating an instance of the Wscript.Network object, and then retrieving the value of the ComputerName property; fortuitously enough, ComputerName happens to be the name of the local computer. We set a variable named strPassword to an empty string (“”), then use this line of code to bind to the local computer:
Set colAccounts = GetObject(“WinNT://” & strComputer)
Having made the connection, we next apply a Filter to ensure that we are working only with user accounts (we don’t want to mess around with printers, services, groups, and other objects that are found in the local Security Accounts Manager):
colAccounts.Filter = Array(“user”)
Applying a filter leaves us with a collection consisting solely of local user accounts; in turn, we then set up a For Each loop to walk through that collection. For each account in the collection we call the ChangePassword method, passing the variable strPassword as both the first parameter (current password) and the second parameter (the new password):
objUser.ChangePassword strPassword, strPassword
We then immediately check the value of the Err object. If ChangePassword succeeds, then Err will be equal to 0; that means the user has a blank password. Alternatively, Err might be equal to -2147023569; that means the method would have succeeded except that, due to local policy, not enough time has elapsed since the last password change. But because the method would have succeeded, we know that the user has a blank password. If either condition is True we echo back the name of the user.
Note. Yes, technically we also change the password, although we’re simply “changing” it to a blank password, which is its current value. That means the user is still able to logon with a blank password. If we wanted to, we could make the second parameter passed to ChangePassword something other than an empty string. In that case, running the script would give the user a new password (whatever value we used as the second parameter).
We then clear the value of the error object (Err.Clear), loop around, and test the next account.
And yes, you can easily modify this script to work against Active Directory accounts. Here’s a sample script that tests all the accounts in the domain fabrikam.com:
On Error Resume Next
Const ADS_SCOPE_SUBTREE = 2
strPassword = “”
Set objConnection = CreateObject(“ADODB.Connection”) Set objCommand = CreateObject(“ADODB.Command”) objConnection.Provider = “ADsDSOObject” objConnection.Open “Active Directory Provider” Set objCommand.ActiveConnection = objConnection
objCommand.Properties(“Page Size”) = 1000 objCommand.Properties(“Searchscope”) = ADS_SCOPE_SUBTREE
objCommand.CommandText = _ “SELECT AdsPath FROM ‘LDAP://dc=fabrikam,dc=com’ WHERE objectCategory=’user'” Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst Do Until objRecordSet.EOF strPath = objRecordSet.Fields(“AdsPath”).Value Set strUser= GetObject(strPath) strUser.ChangePassword strPassword, strPassword If Err= 0 or Err = -2147023569 Then Wscript.Echo strUser.CN End If Err.Clear objRecordSet.MoveNext Loop
If you use this script bear in mind that it tries to change the password for all your user accounts. If you have hundreds or thousands of accounts, the script could take an hour, maybe even more, to complete. There’s nothing wrong with that, just something to be aware of.
And, of course, you can also modify this script to test for other passwords. Want to see if anyone has a password of password? Then just set the value of strPassword accordingly:
strPassword = “password”