Directory Services

Modifying User Properties

Available properties of the ADSI User object vary considerably between different namespace providers. The following code example lists available properties of a particular user and their values.

Dim myUser
Dim userClass
Dim property

Set myUser = GetObject("WinNT://mymachine/username,user")
Set userClass = GetObject(myUser.Schema)

On Error Resume Next

WScript.Echo "Mandatory properties for " & myUser.Name & ":"
For Each property In userClass.MandatoryProperties
	WScript.Echo "	" & property
	WScript.Echo "	" & myUser.Get(property)
Next
WScript.Echo

WScript.Echo "Optional properties for " & myUser.Name & ":"
For Each property In userClass.OptionalProperties
	WScript.Echo "	" & property
	WScript.Echo "	" & myUser.Get(property)
Next

On Error Resume Next is used in this script to continue listing properties, even if an error occurs while attempting to retrieve a property value. The most common error in this case is error &H8000500D, which occurs when attempting to read the value of a property that has not yet been set or is not present for a particular object.

Windows NT UserFlags

User account objects in Windows NT® have a UserFlags property that holds custom user properties in a bit field. Bit masking is a common programming technique which saves storage space by packing a number of Boolean values into a single number. For example, a 16-bit integer could hold the TRUE or FALSE values of 16 different flags, with the value 1 representing TRUE and 0 representing FALSE.

Setting and reading a bit field requires combining the value of the field with a constant, or mask, using logical operators. The following code example defines constants for the flags contained in the UserFlags property.

Const UF_SCRIPT					= &H0001
Const UF_ACCOUNTDISABLE			= &H0002
Const UF_HOMEDIR_REQUIRED		= &H0008
Const UF_LOCKOUT				 = &H0010
Const UF_PASSWD_NOTREQD			= &H0020
Const UF_PASSWD_CANT_CHANGE		= &H0040
Const UF_TEMP_DUPLICATE_ACCOUNT	= &H0100
Const UF_NORMAL_ACCOUNT			= &H0200
Const UF_INTERDOMAIN_TRUST_ACCOUNT = &H0800
Const UF_WORKSTATION_TRUST_ACCOUNT = &H1000
Const UF_SERVER_TRUST_ACCOUNT	= &H2000
Const UF_DONT_EXPIRE_PASSWD		= &H10000
Const UF_MNS_LOGON_ACCOUNT		 = &H20000

These constants may be combined with OR to set them in the bit field, XOR to flip the state of the specified bit, or with AND to retrieve the current state of a particular flag in the field. The following example retrieves and displays the value of the UF_LOCKOUT flag, using the constants defined earlier as bit masks.

Dim myUser

Set myUser = GetObject("WinNT://mymachine/username,user")

If myUser.UserFlags And UF_LOCKOUT Then
	WScript.Echo myUser.Name & " is locked out"
Else
	WScript.Echo myUser.Name & " is not locked out"
End If

The following code example disables the account in the previous code example and prevents the user's password from being changed.

myUser.Put "UserFlags", myUser.UserFlags Or UF_ACCOUNTDISABLE Or _
										UF_PASSWD_NOTREQD
myUser.SetInfo

Unlocking User Accounts

An account lockout policy exists on Windows NT® systems which will lock a user's account after a certain number of failed logon attempts. While this offers a greater level of security against an unauthorized users, it can cause problems for a system administrator when users forget to turn off the CAPS LOCK key before entering their passwords. The following code example unlocks a locked user account.

Dim myUser

Set myUser = GetObject("WinNT://mymachine/username,user")

If myUser.UserFlags And UF_LOCKOUT Then
	myUser.Put "UserFlags", myUser.UserFlags Xor UF_LOCKOUT
End If

Be aware that this code example uses an If statement to verify the current value of the UF_LOCKOUT flag. If the flag is not already set, calling Xor would flip the flag to 1, which is not what the script is supposed to do. Therefore, the code verifies that the flag is set to 1 before flipping it.