As the chief systems administrator, you're responsible for verifying passwords for the local-machine Administrator accounts on your company's Windows NT servers. Your security policies require that all the administrators change these strong passwords every 60 days. However, the administrators seldom use local accounts to log on. Instead, they usually log on with the domain account, which the domain controller authenticates.

Recently, a primary file server lost its network connectivity because someone improperly configured the subnet mask. Because you were unable to log on with the domain account, you tried to log on with a local account, but the password you had on record was incorrect. As a result, you spent a lot of time hacking into the system to regain control and reset the subnet mask. You couldn't determine whether someone changed the password intentionally or whether someone entered the password incorrectly in both the New Password and Confirm Password edit boxes.

With the crisis over, you now want to make sure the rest of the local passwords are correct. Because logging on to each machine locally to confirm the passwords would be time-consuming, you automate the process with two scripts:, which tests whether your passwords are consistent on all the servers in the domain, and, which changes the passwords. Together, these scripts ensure the accuracy and consistency of administrator passwords. uses Perl for Win32 and Win32::AdminMisc functions to locate the target servers and test their passwords. First, the script uses the Win32::GetServers function to compile a list of machines in the domain. Next, the script uses the Win32::NetResource function to attempt a connection to the servers to see whether they are turned on and available on the network. Finally, the script uses the Win32::UserCheckPassword function to test the password on each server.

Listing 1 contains an excerpt from You can find the entire script on the Win32 Scripting Journal Web site ( newsletter/scripting). The script includes comments to help you understand the code. Here are the steps to get working:

  1. Download and install the Perl for Win32 and Win32::AdminMisc extensions on the NT server or workstation where the script will run. Perl for Win32 is available as part of ActiveState's free ActivePerl package ( I used ActivePerl build 518 to create this script. You can use the Perl Package Manager (PPM) to keep your extensions up-to-date. Consult the ppm.html file in the perl\html directory for installation.

    The Win32::AdminMisc extension is available as a free download on the Roth Consulting Web site ( The Win32::Admin Misc page ( contains extensive documentation for the UserCheckPassword and UserChangePassword functions. Carefully review this documentation to ensure that the password policies in your environment won't cause these functions to fail.

    ActivePerl installs easily from a self-extracting executable. To install the Win32::AdminMisc extension, follow the instructions in the README file. The ActivePerl and Roth Consulting Web sites include online documentation for their respective extensions. These sites also have online documentation about using Perl in Win32 systems, so they are excellent resources. In addition, Dave Roth's Win32 Perl Programming: The Standard Extensions (Macmillan Technical Publishing, 1999) is valuable because it contains extensive examples of Perl scripts for systems administrators.

  2. Use the GetServers function to dynamically obtain a list of machines in your domain. To specify the types of machines you want to include in the list, use the appropriate constants. Commonly used constants are

    • SV_TYPE_DOMAIN_CTRL (specifies the inclusion of the PDC)
    • SV_TYPE_DOMAIN_BAKCTRL = (specifies the inclusion of BDCs)
    • SV_TYPE_SERVER_NT = (specifies the inclusion of NT servers that aren't domain controllers)
    • SV_TYPE_WORKSTATION = (specifies the inclusion of NT workstations only)
    • SV_TYPE_NT = (specifies the inclusion of any NT server or workstation)

    The Roth Consulting Web site has the complete list of constants. You can use more than one constant by linking them together with the pipe (|) character, as callout A in Listing 1 shows.

  3. Determine and specify the location for passlog.txt. This file contains the log of successes (i.e., tested password is correct) and failures (i.e., tested password is incorrect or the server was unavailable). Screen 1 contains example passlog.txt output.

    When you specify the path for passlog.txt in the script, use double backslashes instead of single backslashes (e.g., C:\\temp\\passlog.txt instead of C:\temp\passlog.txt). If you prefer, you can write the success and failure logs to separate files or change the output from a text format to a Comma Separated Values (CSV) format. Using the CSV format is helpful if you administer numerous nodes because you can easily open CSV files in Microsoft Excel. contains example code for writing the logs in a CSV file. I included this code as a comment, so if you want to use it, you need to remove the comment symbol (#) from the line that callout B in Listing 1 highlights.

  4. Find out your lockout policy number if you don't know it. The UserCheckPassword function attempts to change the password and reports the success or failure of that action. Consequently, if you execute the script repeatedly with incorrect passwords on some servers, you might lock out accounts if the number of times you run the script equals the lockout policy number that the Account Policy interface window specifies. You can review the Account Policy settings in User Manager. Select Policies and Account to check the password lockout settings. Account lockout doesn't affect the Administrator account unless you have modified your security settings. offers guidelines on how to avoid lockout problems.

  5. Drag the script to a Command Prompt window to test it. The script will test for the domain, Administrator account name, and password that you specify. If the script executes successfully, you'll receive output in passlog.txt and on screen.

    Perl scripts can fail to run in the Command Prompt window if the path to their location contains spaces. If the script doesn't run, use double quotation marks to enclose either the phrase containing the spaces (e.g., C:\winnt\profiles\rlewis\personal\"my scripts"\ or the entire path (e.g., "C:\winnt\profiles\ rlewis\personal\my scripts\").
You can use to change passwords on servers and other types of machines in your domain. Listing 2 contains an excerpt from uses the GetServers function to dynamically obtain a list of all the machines in your domain. However, the Win32 Scripting Journal Web site contains another version of this utility,, that uses an input file rather than the GetServers function to specify which machines to check. Listing 3, page 14, contains an excerpt from

Other than having different input sources, and are the same. Both scripts try to change the password from the old password to the new password you specify. The scripts record successes (i.e., the password changed) and failures (i.e., the password didn't change or the server was unavailable) in the file passchangelog.txt.

Assuming that you've already installed the Perl for Win32 and Win32::AdminMisc extensions (i.e., step 1 in the section), take the following steps to run or

  1. Test and to determine which script is best for your environment. If you use an input file, you'll have greater control over the servers you're targeting for password changes than if you use the GetServers function. However, you need to update the input file whenever you change any servers in your domain. When you use the GetServers function, you don't need to update any files.

    To test, specify the appropriate constants to show the types of machines you want the list to include. Use the same constants that I discussed in step 2 in the section. To test, prepare the input file serverlist.txt. As Screen 2 shows, list the machines you want to include, placing one machine name per line. In, specify the location of the input file. Remember to use double backslashes instead of single backslashes in the path.

    Be aware that using to change passwords on domain controllers (PDCs and BDCs) can cause unpredictable results. Changing BDC passwords isn't necessary or advisable because their local SAM is the domain SAM and they will reflect changes you make to the PDC. Changing the Administrator password on the PDC while you're running the script can cause the script to fail if you're running the script in a user's context.

  2. Determine and specify the location for passchangelog.txt. Remember to use double backslashes in your path. As in, you can write the success and failure logs to separate files or change the output to a CSV format.

  3. Drag the script to a Command Prompt window to test it. If the script doesn't run, use double quotation marks to enclose any spaces in the path. If the script runs successfully, the script will change the local Administrator account password to the one you specified. You'll receive output in passchangelog.txt and on screen. Check the output for servers that weren't available or wouldn't accept the password change. If the password change failed, you need to investigate why. Failures can occur if you have insufficient Administrative authority on the target server or if a connectivity issue caused the password change to fail.

  4. After you've completed your password changes, run the script to verify that all the passwords on all the targeted machines are consistent.

A Bonus
In the September and October issues of the Win32 Scripting Journal, Toby Everett wrote an excellent article, "An Approach to Parallelization," Parts 1 and 2, about how to parallelize processes in a script (i.e., run several processes simultaneously). If you're using to change passwords on numerous nodes, you can improve performance through parallelization. Toby has provided a parallelized version of, which you can find in the file Parallelized Version of on the Win32 Scripting Journal Web site. This .zip file contains two scripts— and—that give you an opportunity to test parallelization code in a real-world situation. Please refer to Toby's two-part article for specific instructions on how to install these scripts.

A Winning Combination
Whether you use or with, you'll have a winning combination. The scripts will ensure that you have consistent, verifiable administrator passwords on all the servers in your domain.