Sunday, May 24, 2009

The purpose of the script (SetLocalPassword.v2.txt - just rename to "SetLocalPassword.vbs") is, to ensure assignment of unique and complex password to a specific local user account (typically the local administrator account) on a Windows client in an Active Directory (AD) domain environment.

The script can be used, if you (for one reason or another) want a specified local user account (e.g. administrator) to be active, but you still want to ensure, that the password used is unique for each computer, that the password is changed regularly (a given period of time) and that you are able to logon using the password at any time. Usually I would recommend customers to just deactivate the local administrator account, or set the password using Group Policy Preferences (preferably different passwords on different security areas), but if these solutions aren’t usable in the environment, “ChangeLocalPassword.vbs” could be the right solution.

The intention is to execute the script as a "Startup Script” within a Group Policy Object (GPO), which is aimed at the relevant computer accounts in AD (as you probably know GPO’s can be filtered by AD security groups, WMI filters, Organizational Units (OU), domain and/or site). This way we ensure that the script is executed in ”SYSTEM" context, in which we can pretty much do anything on the local computer(s). Furthermore, SYSTEM can access network resources on behalf of the computer, as long as the resource in question (a file share in this case) allows “Domain Computers”, the specific AD computer account og “Authenticated Users” to gain access.

It is crucial that the group ”Authenticated Users” is NOT given access to the network share – in that case all users within the domain will be able to read which passwords are used on all computers hit by the GPO. Share permissions (could be a hidden share$) can of course be set to Everyone Full Control, but NTFS must be set to allow only members of the group "Domain Computers" to read and write - domain administrators, and other relevant groups (e.g. helpdesk, supporters, backup account etc.) should also have read access. If you have a Distributed File System (DFS) up and running it could be used as the network share.

This illustrates the scripts cycle:

1. The SYSTEM account is used by the computer during the boot process2. DNS and AD is contacted, and Group Policies are processed (machine policies)3. The GPO with the Startup Script is loaded4. The VBS script is executed (also in SYSTEM context)5. All activity is logged to a local log file (strLocalLog)6. Some preliminary checks are performed, this includes last modification of strLocalStamp and network access (strNetShare)7. A password (strNewPassword) is generated from 4 different criteras (intPasswordLength, intWantNumber, intWantLcase and intWantUcase)8. The username and password (clear text) is logged in a central log file (strnetFile)9. The chosen local user account (strLocalUser) is assigned the newly generated password (only if 8 was completed without any errors)10. A local timestamp file is created or modified if 9 was successfully completed

Some important notes...

First and foremost one must ensure, that the script file the GPO is pointing to cannot be modified by others than the relevant administrators. If a user gets write access to that file, he or she can do anything (locally) on all machines executing the code. This is of course true for any GPO Startup Script used.

Another important thing to note is, that if your users have local admin rights (I hope not), they will be able to “hack” the solution in a couple of ways. First of all they will of course be able to reset passwords for all local user accounts, but if they are a bit clever, they will also be able to take over the SYSTEM account (hint: AT command or PSEXEC) and access the network share we are using – and thus read or modify the log files with all the clear text passwords. But who in the world would allow users to be local administrators in the fist place, right?

A Startup Script will time out if the script takes too long to execute, but we should not have such a problem with this script (normally executed in less than a second). Startup Scripts react differently depending on whether the “Always wait for the network at computer startup and logo” setting is set or not - the script should work in both cases though.

Let’s take a look at the customizable variables.

intDays = 60- default: 60 days between password change

strNetShare = "\\SERVER\SHARE\"- define as a share with the correct NTFS permissions set- is could be a hidden share, perhaps on a DFS- remember a trailing backslash (\) or the script will fail!

strLocalLog = "C:\admpwd.log"- placement of the local log file of all activity (except for the password itself)

strLocalStamp = "C:\admpwd.stp"- placement of the file used as a timestamp

strLocalUser = "test-user"- name the user account to control (e.g. "administrator")

intPasswordLength = 12- the number of characters the password should have (exactly)- must be at least the same as the domains minimum password length

intWantNumbers = 1- set whether or not the password should contain numbers (complexity requirement)

intWantLcase = 1- set whether or not the password should contain lowercase letters (complexity requirement)

intWantUcase = 1- set whether or not the password should contain UPPERCASE letters (complexity requirement)

An example of the strLocalLog (default "c:\admpwd.log") local log file:

The code could most definitely be more optimized (and prettier), but it works like a charm (and pretty fast too) on Windows 2000, Windows XP, Windows Vista, Windows Server 2003, Windows Server 2008 and Windows 7.