Managing Users

The most visible and common administrative task in Active Directory is managing user accounts. Prior to Active Directory, user accounts existed primarily for authorization and security purposes. With Active Directory, the focus has shifted to representing actual people. Information about people in Active Directory is represented in two forms: users and contacts. An object of the user class represents a single person and contains naming, contact, and security information. An object of the contact class is similar, but it omits security information. Contacts are used to keep track of people in an organization who are not network users. Contacts can also represent people external to the organization, such as customers.

The IADsUser Interface

When ADSI binds to any object, it does a quick check of the object's schema class. ADSI then determines whether the class includes an appropriate interface. In the case of objects of the user or contact classes, ADSI provides the IADsUser interface, which encapsulates the information common to both users and contacts. Tables 10-2 and 10-3 show the properties and methods of IADsUser.

IADsUser Property Data Type Matching Attribute in Active Directory Description

AccountDisabled

Boolean

userAccountControl (UF_ACCOUNTDISA BLE flag)

If True, the account is disabled.

AccountExpira tionDate

Date

accountExpires

The date and time when an account expires.

BadLoginAddress

String

Not supported under Active Directory

The address of the computer that caused an account lockout.

BadLoginCount

Long

badPwdCount

The number of failed login attempts.

Department

String

department

The name of the department the user is associated with.

Description

String

description

A description of the user.

Division

String

division

The organizational division the user is associated with.

EmailAddress

String

mail

The user's e-mail address.

EmployeeID

String

employeeID

The employee identification number associated with the user.

FaxNumber

Variant array of strings

facsimileTelephone- Number

List of fax telephone numbers for the user. In Active Directory, the list has a single string.

FirstName

String

givenName

The first, or given, name of the user.

FullName

String

displayName

The full name of the user, including given and last names.

GraceLoginsAllowed

Long

Not supported under Active Directory

The number of times a user can log on after his or her password has expired.

GraceLoginsRemaining

Long

Not supported under Active Directory

The number of grace logins left before account lock out.

HomeDirectory

String

homeDirectory

The UNC path to the user's home directory.

HomePage

String

wWWHomePage

The URL to the user's Web page.

IsAccountLocked

Boolean

Not supported under Active Directory

Is True if account is locked.

Languages

Variant array of strings

Not supported under Active Directory

An array of names of the languages associated withthe user.

LastFailedLogin

Date

badPasswordTime

The date and time of the most recent failed login attempt.

LastLogin

Date

lastLogon

The date and time of the most recent network login.

LastLogoff

Date

lastLogoff

The date and time of the most recent network login.

LastName

String

sn

The last name of the user.

LoginHours

Variant array of Booleans

logonHours

The time periods during each day of the week indicating valid login periods.

LoginScript

String

scriptPath

The path of user's login script.

LoginWorkstations

Variant array of strings

userWorkstations

The network addresses of allowed workstations for the user.

Manager

String

manager

The distinguished name of the Manager object for this user.

MaxLogins

Long

Not supported under Active Directory

The maximum number of simultaneous logins.

MaxStorage

Long

maxStorage

The maximum amount of disk space allowed for the user.

NamePrefix

String

personalTitle

The name prefix, such as Mr. Ms., or Hon., of the user.

NameSuffix

String

generationQualifier

The name suffix (Jr., III) of the user.

OfficeLocations

Variant array of strings

physicalDeliveryOfficeName

The array of end-user locations.

OtherName

String

middleName

The middle name of the user.

PasswordExpirationDate

Date

Not supported under Active Directory

The date and time when thepassword will expire.

PasswordLastChanged

Date

pwdLastSet

The date and time when the password was last set.

PasswordMinimumLength

Long

Not supported under Active Directory

The minimum number of characters allowed in a password.

PasswordRequired

Boolean

userAccountControl (UF_PASSWD_ NOTREQD flag)

If True, a password is required.

Picture

Variant array of bytes

thumbnailPhoto

Image of the user.

PostalAddresses

Variant array of strings

postalAddress Supported but not used by Active Directory

An array of strings with street, city, state, and postal code.

PostalCodes

Variant array of strings

postalCode

The postal code for the user.

Profile

String

profilePath

The user's profile path.

RequireUniquePassword

Boolean

Not supported under Active Directory

If True, user is required to supply unique passwords.

SeeAlso

Variant array of strings

seeAlso

An array of ADsPaths of other objects related to this user.

TelephoneHome

Variant array of strings

homePhone

A list of home telephone numbers.

TelephoneMobile

Variant array of strings

mobile

A list of mobile telephone numbers.

TelephoneNumber

Variant array of strings

telephoneNumber

A list of work-related telephone numbers.

TelephonePager

Variant array of strings

pager

A list of pager telephone numbers.

Title

String

title

The user's title within the organization.

Table 10-2 Properties of the IADsUser interface.

IADsUser Method Description

ChangePassword

Changes the users password. The new and current passwords must be supplied

Groups

Returns a collection of groups the user belongs to.

SetPassword

Sets the password for the user's account.

Table 10-3 Methods of the IADsUser interface.

The IADsUser interface was created while Active Directory was still being designed, so the properties of the IADsUser interface don't always match the attributes available in a user object very well. I'll discuss this in the next section.

Creating Users

Several important items should be considered when creating users. First, you need to understand which attributes are required when the object is created. Second, you need to know what information to put into which attribute. Unfortunately, Active Directory poses several "gotchas" that are compounded by the differences between the IADsUser properties and the Active Directory attributes they are mapped to.

One such "gotcha" is the address attributes for a user. While the IADsUser interface provides the PostalAddress property, using this property to access the postal address of a user will not work under Active Directory. You shouldn't use the PostalAddress property because Active Directory uses separate attributes for street (streetAddress), city (l), state (st), and postal code (postalCode). With Active Directory, you must use the Get method of the IADs interface to access these attributes.

Naming Attributes

Active Directory requires two attributes to be set when creating a new user object. The first is the cn (Common-Name) attribute. This is simply the name of the object and may or may not relate to the name of the user. As with all objects in Active Directory, the name of the object must be unique within its container. If a user is added to a container that already has an object with the same name, the create operation fails.

As I mentioned in Chapter 9, I've talked with several administrators who think that users with the same name cannot be represented in the same Active Directory container. This misperception is created by the behavior of the New User wizard in the Active Directory Users and Computers snap-in. The New User wizard uses the text in the Full Name field as the value for the cn attribute. The Full Name field is dynamically created as information is typed into the First Name, Initials, and Last Name fields.

In practice, the cn value is the full name of the user, but any unique string can be used, including the logon name. (See the next paragraph). A limitation of using a unique string is that the Active Directory user interface uses the cn attribute value in several places instead of the more appropriate displayName attribute. Exchange 2000 Server, however, does use the displayName attribute correctly in its various user interface components such as the Address Book.

The second required attribute, and a potential source of conflict, is the sAMAccountName attribute. This is the logon name used by versions of Windows prior to Windows 2000. With Active Directory, the string the user types in at the log-on prompt can be the sAMAccountName value or a user principal name (UPN). The UPN is more flexible than the sAMAccountName attribute in that it consists of two parts—the first being a user name followed by the at-sign (@), and the second a Domain Name System (DNS) address known as the UPN suffix. Generally, the UPN of a user will be their e-mail address, charles@coppersoftware.com or charles.oppermann@coppersoftware.com, for example. The UPN is useful because it gives users a common and easy-to-remember identifier—their e-mail address—to log onto the network.

Regardless of the UPN, the sAMAccountName attribute must still be unique in the domain. There are two ways to avoid a conflict with duplicate values for the sAMAccountName attribute. A simple method is to attempt to add the user and detect whether an error has occurred. Another way is to query the local global catalog (GC) server with the proposed value for sAMAccountName, as the sAMAccountName attribute is among those included in the global catalog subset. The LDAP query string would be (sAMAccountName=proposedvalue). Since the sAMAccountName attribute is also an indexed attribute, the global catalog server can perform an efficient search. If an object is returned by the search, the proposed name is already used. With either method, if a name conflict is detected, the script can then prompt for another account name or attempt to generate a unique one. Account names must be 20 characters or less, and generally do not contain spaces.

Create User Script

Listing 10-2 shows a script, available on the companion CD, that adds a user to Active Directory. You can easily modify this sample to read in the information from a text file or a database to create multiple users at one time. The script shows how to create a user object in the Users container and set various attributes using the IADs and IADsUser interfaces. Notice that the Create method of the IADsContainer interface, which was discussed in Chapter 6, is used to create the user object. All new objects in Active Directory are created with the Create method of IADsContainer.

 <job >
<reference gu/>
<script language="VBScript">
`
` CreateUser - Creates example user
`
` Strings used to identify and describe the new user
` Logon name
strUserAcct = "JAUser"
strFullName = "Joe A. User"
strFirstName = "Joe"
strLastName = "User"
strPassword = "mypassword"
` Lots of confusion on these.  Wizard uses initials as a "middle initial"
strMiddleName = "Average"
strInitials = "A"
` Descriptive info
strUserDesc = "Example user for testing purposes."
strTelephone = "888-555-1212"
strStreet = "One Microsoft Way"
strCity = "Redmond"
strState = "WA"
strZIPCode = "98052" ` Display info
WScript.Echo "Creating new user `" & strFullName & "`..."
` Bind to the rootDSE and get the default domain partition
Set adsRootDSE = GetObject("LDAP://rootDSE")
strDomainDN = adsRootDSE.Get("defaultNamingContext")
` Bind to the Users container of the domain
strADsPath = "LDAP://CN=Users," & strDomainDN
Set adsContainer = GetObject(strADsPath)
` Go to the next line if an error occurs
On Error Resume Next
` Create the object in the container using the full user name
Set adsUser = adsContainer.Create("user", "cn=" + strFullName)
` Set the down-level account name for the user (<20 characters)
adsUser.Put "sAMAccountName", strUserAcct
` Set the UPN for the user
adsUser.Put "userPrincipalName", strUserAcct
` Update server with required properties
adsUser.SetInfo
` Check for errors
If Err.Number <> 0 Then
    ` Check to see whether user already exists error
    If Err.Number = &H80071392 Then
        ` Display error message and exit
        WScript.Echo "The user name `" & strFullName & "` already exists."
        WScript.Quit 1
    Else
        WScript.Echo "Unexpected error creating user." & vbNewLine & _
            Err.Description & " (" & Hex(Err.Number) & ")"
        WScript.Quit 1
    End If
End If
` Turn off error handling
On Error GoTo 0
` Use IADsUser properties to set other pieces of data
` Refresh the local property cache with new user info
adsUser.GetInfo
` Set the user password.  SetInfo must be called beforehand (above)
adsUser.SetPassword strPassword
` Require the user to change password on login
adsUser.Put "pwdLastSet", 0
` Enable the account (the default when created is disabled)
adsUser.AccountDisabled = False
` Set the display name of the user
adsUser.FullName = strFullName
` Set name information of the user
adsUser.FirstName = strFirstName
adsUser.LastName = strLastName
adsUser.OtherName = strMiddleName
adsUser.Put "initials", strInitials
` Set the description using the Description property
adsUser.Description = strUserDesc
` Set the telephone number
adsUser.TelephoneNumber = strTelephone
` Set the address information
` Must use Active Directory attributes, not PostalAddress property.
adsUser.Put "streetAddress", strStreet
adsUser.Put "l", strCity
adsUser.Put "st", strState
adsUser.Put "postalCode", strZIPCode
` Apply the properties to the directory
adsUser.SetInfo
` Release objects
Set adsUser = Nothing
Set adsContainer = Nothing
` Finish
WScript.Echo "User created successfully."
</script>
</job>

Listing 10-2 CreateUser.wsf shows how to create an example user.

When you run the CreateUser script, a user named "Joe A. User" is created in the Users container. Figure 10-2 shows the Properties dialog box for the new user in Active Directory Users and Computers.

Figure 10-2 Properties dialog box for the new user created with the CreateUser script.

Default User Values

If you do not explicitly set the properties and attributes listed in Tables 10-4 and 10-5 when creating a new user, Active Directory will use default values.

IADsUser Property Default Value

AccountDisabled

True

AccountExpirationDate

1/1/1970. This indicates that the account never expires.

PasswordLastChanged

Default is 0, which means the user must change the password at next logon.

PasswordRequired

False

Table 10-4 Default property values for a user object.

User Attribute Default Value

memberOf

If not specified, this attribute remains empty; however the Domain Users group is set as the primary group for the user.

nTSecurityDescriptor

A security descriptor is created from the combination of the user class and parent object's security descriptors.

objectCategory

Set to Person. This attribute is automatically set by Active Directory and cannot be modified.

Table 10-5 Default attribute values for a user object.

Passwords

The password for a user account is contained in the unicodePwd attribute of the user object. The actual password is stored in the directory using an encryption technique known as one-way format (OWF). You cannot directly read or write to the unicodePwd attribute even if you have the appropriate security privileges. This restriction prevents the password from being transmitted in clear text over the network.

In order to set or change a user's password, you must use the SetPassword or ChangePassword methods of the IADsUser interface. The specific method to use depends on the security context of the application.

The SetPassword method accepts a string parameter and uses it to replace the current password. This method can be used by administrators to reset a user's password. When SetPassword is used in a program that creates a user object, the pwdLastSet attribute should be set to 0, which indicates that the user must change her password the next time she logs on. In Active Directory Users and Computers, this option is available on the Account tab of the user's Properties dialog box, in a check box named User Must Change Password At Next Logon. It's good security practice to require users to change their password to something of their own choosing, rather than use a default password, which could be compromised. The CreateUser script shown in Listing 10-2 sets the pwdLastSet attribute to 0.

The ChangePassword method accepts two parameters: the old password and the new password. Because it requires knowledge of the existing password, this method can be used by end users.

Listing 10-3 shows a script available on the companion CD that can be used to change a password. It accepts three command-line parameters. The first is the name of the user, for example, "Joe A. User". Any format recognized by Windows can be used, such as domainname\username or username@domainname.com. The second and third parameters are the current and new passwords, respectively. Note that quotation marks are required for any parameters that have spaces. Here's an example:

 changepassword "Joe A. User" mypassword mynewpassword 

This script uses the ADSI object named NameTranslate to retrieve the user's distinguished name in the directory. Retrieving this information allows us to avoid searching the directory for the user object. NameTranslate uses the DsCrackNames API. NameTranslate is part of Windows 2000; other platforms require the Active Directory Client to be installed to use it.

 <job >
<reference gu/>
<script language="VBScript">
`
` ChangePassword  
  Accepts a name and prompts for old and new passwords
`
` Accepts a username and resets the password
` Name must be full name ("Charles Oppermann") or be in
` domainname\username format ("coppersoftware\charles")
`
` Check whether there is a command-line argument
Set wshArguments = WScript.Arguments
If (wshArguments.Count = 3) Then
    ` Treat the command-line argument as the name to use
    strUser = wshArguments(0)
    strOldPassword = wshArguments(1)
    strNewPassword = wshArguments(2)
Else
    WScript.Echo "Incorrect number of arguments." & vbNewLine & _
        "Usage:  ChangePassword.wsf username " & _
        "oldpassword newpassword"
    WScript.Quit 1
End If
` Use NameTranslate to look up the computer in the directory
Set adsNameTranslate = CreateObject("NameTranslate")
adsNameTranslate.Init ADS_NAME_INITTYPE_GC, vbNullString
` Set the user name into nametranslate
` Specify unknown format, so that system will guess
adsNameTranslate.Set ADS_NAME_TYPE_UNKNOWN, strUser
` Get the DN of the object
strDN = adsNameTranslate.Get(ADS_NAME_TYPE_1779)
` Make DN an ADsPath by prefixing the ADSI provider
strADsPath = "LDAP://" & strDN
` Bind to user object
Set adsUser = GetObject(strADsPath) ` Confirm change
strPrompt = "Change password for " & adsUser.FullName & " from `" & _
    strOldPassword & "` to `" & strNewPassword & "`?"
nConfirmed = MsgBox(strPrompt, vbYesNo, "Change Password")
If nConfirmed = vbYes Then
    ` Go to the next line if an error occurs
    On Error Resume Next
    ` Change the password
    adsUser.ChangePassword strOldPassword, strNewPassword
    ` Check for errors
    If Err.Number <> 0 Then
        ` Display error message
        Select Case (Err.Number)
            Case &H80070056
                WScript.Echo "The specified password for " & _
                    adsUser.FullName & " is not correct."
            Case &H800708C5
                WScript.Echo "The specified password does not " & _
                    "meet policy requirements."
            Case Else
                WScript.Echo "Unexpected error changing password." & _
                    vbNewLine & Err.Description & " (" & _
                    Hex(Err.Number) & ")"
        End Select
    Else
        WScript.Echo "Password successfully changed for " & _
            adsUser.FullName
    End If
End If
</script>
</job>

Listing 10-3 ChangePassword.wsf shows how to change the password for an existing user.

The userPassword attribute, part of the person object class, is not used in Active Directory.


Working with Exchange 2000 Server

Microsoft Exchange 2000 Sever is Microsoft's latest version of its enterprise e-mail server. Exchange 2000 uses Active Directory to store configuration data for itself and extends many classes with new attributes and display specifiers. When a user or contact is mailbox-enabled, Exchange 2000 has a mailbox for the user or contact and has updated the person's information in Active Directory to indicate their e-mail address and the location of their mailbox.

A common task when creating users is to create an Exchange 2000 mailbox at the same time. Exchange 2000 makes this easy by providing management interfaces that aggregate some existing ADSI interfaces. This is done by using the ADSI Extension feature. While I won't go into the details, suffice to say that the properties and methods of the Exchange 2000 IMailboxStore and IMailRecipient interfaces are available when bound to a user or contact class object.

The IMailboxStore and IMailRecipient interfaces are part of the Collaboration Data Objects for Exchange Management (CDOEXM). CDOEXM extends ADSI and Collaboration Data Objects (CDO) to include properties and methods to manage Exchange 2000. Although CDO and CDOEXM are not covered in this book, I wanted to mention these technologies so that you are aware of them.

For more information about creating mailboxes and sending e-mail programmatically in Exchange 2000 Server, along with sample scripts, see the Exchange folder on the companion CD. To learn more about CDO, CDOEXM, and Exchange 2000 development, I suggest the Microsoft Press book Programming Collaborative Web Applications with Microsoft Exchange 2000 Server, by Mindy Martin. (And you thought the title of this book was long!)




MicrosoftR WindowsR 2000 Active DirectoryT Programming
MicrosoftR WindowsR 2000 Active DirectoryT Programming
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 108

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