Managing User Account Properties

   

Managing User Account Properties

Of all of the interfaces in the Windows NT service provider, the IADsUser interface provides the greatest number of properties and methods to programmatically manipulate user accounts. The great number of exposed properties and methods involved should be of little surprise to even a novice systems administrator, as the majority of daily administrative tasks are focused around user account management. Using the IADsUser interface, you can build applications and scripts that tie together the administrative processes previously performed using individual, manual steps.

When creating a new user account, you typically have a default set of groups for which the user requires membership, as well as a home directory to create. In addition, the user home directory must be shared and permissions applied to allow it to be mapped from a login script and to restrict unauthorized access. After entering the appropriate user name, full name , and description, you should also populate the profile path and home directory path fields in the SAM to let Windows NT know where it should look to find the user's home directory and roaming profile. Finally, the information regarding the new user account must be distributed to the user (or more likely his or her manager) in a secure, efficient manner. By passing information from ADSI to an application that utilizes an object model (such as Outlook), this too can be accomplished using programmatic methods.

Investing time in the creation of a script to automate workflow processes is sure to increase customer satisfaction because the automated workflow processes will no longer be prone to the errors encountered in the manual workflow process. Using the methods and properties implemented in the IADsUser interface, you can manipulate almost all of the configurable options available in the User Properties dialog box in User Manager for Domains.

Manipulating the User FullName Property

As shown in Figure 4.1, when creating a new account, most enterprises set an appropriate value for the Full Name data field to help identify the user account. This is typically limited to the user's first and last name and perhaps the middle initial if applicable .

Figure 4.1. User Properties dialog box in User Manager for Domains

graphics/04fig01.gif

Some enterprises may choose to implement this field as a field-delimited record to incorporate better interoperability with programmatic methods for manipulating the SAM. By taking such an approach, you can create Web-based tools that can parse down the field into individual elements providing Active Directory-like properties for Windows NT environments.

Querying the User FullName Property Using Visual Basic

To return the bound user's full name as a string, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as String RetVal = User.Fullname Debug.Print RetVal 
Setting a New Value for the User FullName Property Using Visual Basic

To set a new value for the bound user's Full Name field in the SAM, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String Dim NewFullName as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " NewFullName = "  New_Value_For_Full_Name_Field  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") User.Fullname = NewFullname User.SetInfo 

Manipulating the Description Property

The Description property allows you to enter data regarding the employee, including geographic location of the account owner, department, cost center, employee identification number, or any other information about the user you desire .

Note

If a naming standard is not currently in place for this field, you should consider forcing its data to comply with a specific delimited standard to improve the ability to query the data. Without the attributes of the Active Directory available to Windows NT users, the ability to target a specific group of users is limited. By implementing meaningful field-delimited data in the Description (and FullName ) properties, you can significantly increase the power of programmatic administration functions .


Querying the Description Property Using Visual Basic

To return the currently bound user object's Description property as a string, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as String RetVal = User.Description Debug.Print RetVal 
Setting a New Value for the Description Property Using Visual Basic

To set a new value for a user's Description property, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String Dim NewDescription as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " NewDescription = "  New_Value_For_Description_Field  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") User.Description = NewDescription User.SetInfo 

Note

If you want to query an individual element within the contents of a field-delimited property, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String Dim Delimiter As String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Delimiter = "" Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as String RetVal = User.Description Dim FirstDelim As Integer Dim DescriptionLength As Integer Dim ParsedElement As String Dim TerminalCondition As Boolean StartPosition = 1 While TerminalCondition <> True      FirstDelim = InStr(1, RetVal, Delimiter)      If FirstDelim = 0 Then           TerminalCondition = True      Else           DescriptionLength = Len(RetVal)           ParsedElement = Left(RetVal, FirstDelim - 1)           Debug.Print Trim(ParsedElement)           RetVal = Right(RetVal, (DescriptionLength - FirstDelim))      End If Wend Debug.Print Trim (RetVal) 

Manipulating User Passwords

One of the most common administrative tasks for any help desk or access control group administrator is user account password management. This involves resetting a password to a known value and forcing the user to change the password on his next login.

Users also participate in these activities by entering their current password and entering a new value for their password. Unlike an explicit password set operation, these operations can be performed simply with knowledge of the current password by using a user-level privilege account.

Querying a User Password Stored in the SAM

It is important to note that this field in the SAM cannot be accessed programmatically by any tool, including ADSI. If you want to find the value of a user password, you must instead use a brute-force password hash comparison utility such as L0phtCrack or one of the many other tools available on the Internet for such purposes.

Setting a New Value for a User Password Using Visual Basic

To use the SetPassword method, the calling user need not know the original user password, but must possess administrative rights in the domain to perform the action.

If you want to reset a user password without knowing the original password, use the following code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim NewPassword as String NewPassword = "Superm@n99" Call User.SetPassword(NewPassword) 

Note

Obviously, you should replace the value of Superm@n99 with a password of your choosing. This value can be populated using any string value that does not violate Windows NT's rules for valid passwords .


Changing a User Password Using Visual Basic

When users change passwords, they must enter both the current password as well as the new password they desire to use. This simple security method enables non-administrative users to change their own passwords without having any more than simple user-level privileges in the domain. Use the following Visual Basic code to change the password for a user account where the current password is known:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim NewPassword as String Dim OldPassword as String NewPassword = "Superm@n26" OldPassword = "B@tm@n74!" Call User.ChangePassword(OldPassword, NewPassword) 

Tip

When using a Web server to implement password changes, to ensure that passwords are not sent over the wire in clear text between the Web server and the client, all pages dealing with user password information should be encrypted using a Secure Sockets Layer (SSL) connection .


Manipulating a User Flag

To find the status of user flags in the SAM, use the Get method of the IADs interface to retrieve the flag setting. Unlike other properties manipulated using ADSI, these properties require a bit of work to query and set because they are manipulated using bitwise operators. The following table defines some constants that represent the hex values of four of the five status flags shown in User Manager:

0x00002 ADS_UF_ACCOUNTDISABLE
0x00010 ADS_UF_LOCKOUT
0x00040 ADS_UF_PASSWD_CANT_CHANGE
0x10000 ADS_UF_DONT_EXPIRE_PASSWD

Note

Notice that there is no flag for the User Must Change Password at Next Logon setting. This is because this setting is not controlled by a user flag, but rather is controlled simply by setting the PasswordExpired property to 1 for the user account .


There are many user flags available to the developer for manipulation and control of a user account. A complete listing of ADSI constants can be found in Appendix B, "ADSI 2.5 Programmer's Reference"

To set and query these hex values, use the Or, Xor, and And operators to manipulate these flags in the following general manner:

  • The Or operator is used to initially set a bit (as in the case of a new account creation).

  • The Xor operator is used to toggle the status of the flag (from enabled to disabled, or vice-versa).

  • The And operator is used to query the value held in the SAM.

Querying the Value of a User Flag Using Visual Basic

To find the value of a specific flag using Visual Basic, use the following general syntax:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long Flags = User.Get("UserFlags") If (Flags And &H10000) <> 0 Then     Debug.Print "The specified user account is configured so that the password never graphics/ccc.gif expires." End If 

Note

Notice you are "And-ing" the 0x10000 hex value (Password Never Expires) with the user flags and then evaluating the result of the operation. If anything other than 0 is returned, you can be sure that the Password Never Expires status flag is set for the bound account .


Toggling a User Flag Using Visual Basic

Likewise, you can toggle these flags by using the Put method and the Xor operator to modify the bit to its complement. Consider the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long  Flags = User.Get("UserFlags") User.Put "UserFlags", (Flags Xor &H10000) User.SetInfo 

After finding the value of UserFlags you perform an Xor operation on the current UserFlags property to toggle the bit value. Next, you write the new value back into the directory with the SetInfo method.

Tip

By simply changing the Xor operator to an Or operator, you can use the preceding code to set the initial value of a status flag .


Manipulating the User Must Change Password at Next Logon Status Flag

In most cases, after you reset a password, the User Must Change Password at Next Logon status flag should be set to ensure that the default password does not become the new password for the user account.

You may want to incorporate this functionality in the password change procedure code if the security policy for your enterprise dictates that even IT personnel are not permitted to have knowledge of user account password information.

Note

Behind the scenes, Windows NT expires the password to force the user to change the account password upon next logon. For this reason, NT does not allow you to set this flag and the Password Never Expires flag at the same time. Although this is obvious when using the User Manager GUI (due to the error dialog box raised), when using programmatic methods to manipulate properties and methods, this is not nearly as apparent .


Querying the User Must Change Password at Next Logon Status Flag Using Visual Basic

To find the current value of the PasswordExpired user flag, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim PasswordExpired As Integer PasswordExpired= User.Get("PasswordExpired") If PasswordExpired = 1 Then     Debug.Print "The user account is configured so that the password must be changed on graphics/ccc.gif next logon." Else     Debug.Print "The user will NOT be required to change the account password on next graphics/ccc.gif logon." End If 

Note

If the PasswordExpired property returns a value of 1 when queried, the password has expired and must be changed upon next logon. If the value of PasswordExpired returns 0, the password has not yet expired .


Setting a New Value for the User Must Change Password at Next Logon Status Flag Using Visual Basic

To expire a user account password immediately, set the PasswordExpired property to a value of 1, as shown in the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim PasswordExpired As Integer  User.Put "PasswordExpired", 1 User.SetInfo 

Tip

In this case, you are using the IADs Put method to force a new value for the PasswordExpired property for the user account. If you want to remove the PasswordExpired bit for a user account, simply set this property value to 0 .


Manipulating the User Cannot Change Password Status Flag

Although this flag is not often used by enterprises for user accounts (frequent user password changes should be encouraged), it can nevertheless be programmatically manipulated. Using the user flag bitwise operations described previously, this bit can be queried, set, and toggled.

Querying the User Cannot Change Password Status Flag Using Visual Basic

To prevent users from having the right to change their own passwords, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long  Flags = User.Get("UserFlags") If (Flags And &H00040) <> 0 Then     Debug.Print "The specified user account is configured so that the password cannot be graphics/ccc.gif changed." End If 
Setting the Value for the User Cannot Change Password Status Flag Using Visual Basic

There may be cases (such as when creating a new account) where you must ensure that the value of this bit is set to a specific value. Use the following Visual Basic code to explicitly set the User Cannot Change Password status flag in the SAM:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long  Flags = User.Get("UserFlags") User.Put "UserFlags", Flags OR &H00040 User.SetInfo 
Toggling the Value for the User Cannot Change Password Status Flag Using Visual Basic

To toggle the value of the User Cannot Change Password status flag, you can use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long Flags = User.Get("UserFlags") User.Put "UserFlags", Flags XOR &H00040 User.SetInfo 

Manipulating the Password Never Expires Status Flag

When creating a service account, it is always advisable to set the ADS_UF_DONT_EXPIRE_PASSWORD user flag on the account to prevent service startup failures due to password synchronization issues. By setting this flag, the specified account is not subject to the maximum password age setting in the domain's account policy configuration, and will not be forced to change passwords on a periodic basis.

Querying the Password Never Expires Status Flag Using Visual Basic

To query the current password expiration policy affecting the bound user account, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long  Flags = User.Get("UserFlags") If (Flags And &H10000) <> 0 Then     Debug.Print "The specified user account is configured so that the password never graphics/ccc.gif expires." End If 
Setting the Password Never Expires Status Flag Using Visual Basic

To allow a user account to be unaffected by the maximum password age restrictions in the domain (if applicable), use the following Visual Basic code to explicitly set the ADS_UF_DONT_EXPIRE_PASSWORD bit:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long Flags = User.Get("UserFlags") User.Put "UserFlags", Flags OR &H10000 User.SetInfo 
Toggling the Password Never Expires Status Flag Using Visual Basic

To toggle the current value of the Password Never Expires field in the user's SAM record, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim Flags As Long Flags = User.Get("UserFlags") User.Put "UserFlags", Flags XOR &H10000 User.SetInfo 

Manipulating the Account Disabled Status Flag

ADS_UF_ACCOUNTDISABLE is a user flag that can be raised in the SAM record for any user account. The IADsUser interface also implements this functionality as a property for easier manipulation.

Note

If you prefer to use bitwise operators, you can manipulate the Account Disabled user flag using the same techniques as shown for the Password Never Expires flag. Simply change the hex value passed as an argument of the IADs Put method from 0x10000 (&H10000) to 0x2 (&H2) .


Querying the Account Disabled Status Flag Using Visual Basic and the AccountDisabled Property

To enable easier manipulation of the Account Disabled status flag, Microsoft exposed the AccountDisabled property in the IADsUser interface. Use the following Visual Basic code to determine whether an account is currently enabled or disabled:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Boolean  RetVal = User.AccountDisabled Debug.Print RetVal 
Setting a New Value for the Account Disabled Status Flag Using Visual Basic and the AccountDisabled Property

To enable or disable a user account, simply set the IADsUser AccountDisabled property to the proper Boolean value, as shown in the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim NewValue as Boolean  NewValue = False User.AccountDisabled = NewValue User.SetInfo 

Enumerating a Domain to Report All Disabled Accounts Using Visual Basic

In some enterprises, it may be useful to generate a list of all accounts that are currently disabled for auditing purposes. To perform such an action, simply enumerate all user accounts in a given domain (or local SAM) and use a conditional to display any accounts that are currently disabled .

Consider the following Visual Basic code to generate a report of all disabled accounts for a given domain:

 Dim Domain As IADsContainer Dim DomainName as String Dim UserAccount As IADsUser Dim Counter As Integer Counter = 0 DomainName = "  Target_Domain_Name  " Set Domain = GetObject("WinNT://" & DomainName) Domain.Filter = Array("User") Debug.Print "The following accounts are disabled in domain: " & Domain.Name For Each UserAccount In Domain     If UserAccount.AccountDisabled = True Then         Debug.Print UserAccount.Name         Counter = Counter + 1     End If Next If Counter = 1 Then     Debug.Print "Only 1 user account in the " & Domain.Name & " domain is disabled." Else     Debug.Print Counter & " user accounts are disabled in the " & Domain.Name & " domain." End If 

Manipulating the Account Locked Out Status Flag

Depending on the Account Policy configuration for the domain, account lockout conditions can be a tremendous burden on system administrators. As part of the IADsUser interface, you can both query and reset account lockout conditions.

Tip

As was the case with the AccountDisabled property, the Account Lockout user flag can also be manipulated using bitwise operators .


Querying the Account Locked Out Status Flag Using Visual Basic and the IsAccountLocked Property

To find out if a user account has been locked out, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Boolean  RetVal = User.IsAccountLocked Debug.Print RetVal 
Unlocking a User Account Using Visual Basic and the IsAccountLocked Property

To unlock a currently locked-out user account, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") If User.IsAccountLocked = True Then      User.IsAccountLocked = False      User.SetInfo End If 

Note

Despite the hours of entertainment derived from locking out the user accounts held by your manager and teammates, Microsoft does not allow you to set the IsAccountLocked property to True in the release version of ADSI 2.5 .


Resetting All Locked-Out User Accounts for a Domain

The following code enumerates all user accounts in the domain and resets all accounts to an enabled state:

 Dim Domain As IADsContainer Dim UserAccount As IADsUser Dim Counter As Integer Dim DomainName as String Counter = 0 DomainName = "  Target_Domain_Name  " Set Domain = GetObject("WinNT://" & DomainName) Domain.Filter = Array("User") For Each UserAccount In Domain      If UserAccount.IsAccountLocked = True Then           Debug.Print UserAccount.Name           UserAccount.IsAccountLocked = False           UserAccount.SetInfo           Counter = Counter + 1      End If Next If Counter = 1 Then     Debug.Print "Only 1 user account in the " & Domain.Name & " domain was unlocked." Else     Debug.Print Counter & " user accounts were unlocked in the " & Domain.Name & " graphics/ccc.gif domain." End If 

If this script is run on a regular basis, there is little reason to continue permitting lockout conditions to exist in the domain. Be sure to consult with your security organization before implementing such code .



   
Top


Windows NT. 2000 ADSI Scripting for System Administration
Windows NT/2000 ADSI Scripting for System Administration
ISBN: 1578702194
EAN: 2147483647
Year: 2000
Pages: 194
Authors: Thomas Eck

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net