Chapter 9. Computer Roles

Computers play different roles in the IT infrastructure. It is important for system administrators to know the role played by any computer; after all, the techniques used to manage a workstation are usually quite different from those used to manage a domain controller. Scripting provides a way for administrators to easily identify computers and their roles, and to modify those roles as needed.

In This Chapter

Computer Roles Overview

In enterprise settings, computers are not just pieces of hardware used to type memos or prepare spreadsheets; computers are dynamic role players that are largely responsible for ensuring that the IT infrastructure runs at peak efficiency. System administrators might supervise the network, but computers are responsible for carrying out such key tasks as authenticating user logons, handing out IP addresses, and maintaining the integrity of the Active Directory® directory service.

Of course, no entity could be entrusted with such important duties without having to undergo authentication itself; after all, you would not want users to take any old computer and configure it to be a domain controller or a global catalog server. Instead, computers are security principals within Active Directory. To have full access to network resources, computers must have valid accounts within Active Directory. In turn, the fact that computers are security principals and role players charges system administrators with:

  • Creating, managing, and deleting computer accounts in Active Directory.

  • Managing the roles played by computers. These management tasks include such things as identifying the roles played by a single computer, enumerating all the key role players in Active Directory, and changing computer roles as circumstances dictate.

By using both Windows Management Instrumentation (WMI) and Active Directory Service Interfaces (ADSI), you can create scripts that help you manage computers as dynamic role players.

Managing Computer Accounts

In Active Directory, computers are security principals, just like users. This means that computers must also have accounts and passwords, just like other security principals. To be fully authenticated by Active Directory, a user must not only have a valid user account, but he or she must also log on to the domain from a computer that has a valid computer account. If a user attempts to log on from an unauthorized computer, authentication will fail and the user will be denied access to important Active Directory capabilities such as Group Policy, roaming user profiles, remote installation, Quality of Service (QoS) networking, DNS, and applications that use Active Directory as a data store.

You cannot create computer accounts for computers running Microsoft® Windows® 95, Microsoft® Windows® 98, Microsoft® Windows® Millennium Edition, and Microsoft® Windows® XP Home Edition because these operating systems do not adhere to Active Directory security requirements. As a result, computers running these operating systems cannot join a domain, and users logging on from these computers will not have access to the complete range of Active Directory resources and services.

Attributes of an Active Directory Computer Account

Each computer account in Active Directory is an instance of the Computer class. This class has six mandatory attributes. (Attributes are also referred to as properties.) Mandatory attributes are properties that each account must have; you cannot create a computer account in Active Directory unless that account has each of the following attributes:

  • Common-Name

  • SAM-Account-Name

  • Instance-Type

  • NT-Security-Descriptor

  • Object-Category

  • Object-Class

Note

Note

When you create a computer account, you need to specify that the account is for a computer and provide the Common-Name and the SAM-Account-Name. The other mandatory attributes will automatically be created for you.

In addition to the six mandatory attributes, the Computer class has scores of optional attributes that are inherited from the User class. These attributes vary in usefulness. Some, such as computer location, are extremely useful to administrators; by configuring the computer location attribute, administrators can use Active Directory as a way to identify the physical location of every computer in the organization.

Other attributes are meaningless when applied to a computer; for example, computers do not have user profile paths or home phone numbers (although Active Directory does not prevent you from assigning a user profile path or a home phone number to a computer). Although these might seem nonsensical, the Computer class possesses these attributes simply because the class was derived from the User class. As such, the Computer class inherited all the attributes found in the User class.

A subset of the attributes useful for working with computer accounts are listed in Table 9.1. All of these attributes are available after the computer account has been created.

Table 9.1. Attributes of the ADSI Active Directory Computer Account

Attribute

Description

accountDisabled

Boolean value indicating whether the account is enabled for use.

canonicalName

Name of the computer in canonical form (for example, Server5.fabrikam.com).

cn

Common name of the computer (for example, Server5).

company

Name of the company responsible for the computer. This attribute can be useful in large organizations that encompass multiple companies.

department

Name of the department responsible for the computer.

description

Description of the computer. The description often includes information about the roles played by the computer.

distinguishedName

Distinguished name of the computer (in the format, CN=Server5, OU=Finance, DC=fabrikam, DC=com).

division

Name of the division responsible for the computer.

dnsHostName

Name of the computer as registered with the DNS server.

location

Physical location of the computer (often in the format Building Name/Floor Number/Room Number).

name

Name of the computer.

operatingSystem

Name of the operating system (such as Windows® 2000 Professional).

operatingSystemServicePack

ID string for the latest service pack installed on the computer (for example, SP4 indicates that the last service pack installed was service pack 4).

operatingSystemVersion

Version number for the operating system (for example, 5.0).

sAMAccountName

Logon name used to support clients and servers from a previous version of Windows (such as Microsoft® Windows NT® 4.0 and earlier, Windows 95, and Windows 98). The value of the sAMccountName attribute must be less than 20 characters to support computers running these operating systems.

whenChanged

Date the computer account was last modified.

whenCreated

Date the computer account was initially created.

Retrieving Basic Logon and Computer Information

Logon scripts often require basic information about a user and his or her computer. For example, if you know the user name, you can connect to the user account object in Active Directory and determine the groups that the user belongs to. In turn, you can then make certain resources available to that user, depending on group membership. Of course, your ability to do that hinges on your ability to determine the name of the user who just logged on.

Likewise, if you know the computer name or the site name, you can map appropriate drives ahead of time for users. For example, a computer located at site A might have drives mapped to file server A, while a computer located at site B might have drives mapped to file server B.

Some of this information (user name, computer name, and domain name) can be returned using the Windows Script Host (WSH) Network object. However, there are at least two limitations to the Network object.

  • The Network object returns only the user logon name (for example, kenmeyer). By itself, this name cannot be used to bind to the user account object in Active Directory. Instead, you need a distinguished name similar to CN=KenMeyer, OU=Management, DC=Fabrikam, DC=com. The same is true for computers.

  • The Network object can return only the names of the user, the domain, and the computer; it cannot provide information about items such as the forest name or the site.

If you need this additional information, or if you need to bind to the user or computer account in Active Directory, you can instead use the IADsADSystemInfo interface, an ADSI interface implemented in the ADSystemInfo object (Activeds.dll). This object returns the attributes shown in Table 9.2.

Table 9.2. Attributes of the ADSystemInfo Object

Attribute

Description

UserName

Distinguished name for the logged-on user. The distinguished name is in the form CN=KenMeyer, OU=Management, DC=Fabrikam, DC=com.

ComputerName

Distinguished name for the computer account.

SiteName

Site in which the computer account is located.

DomainShortName

“Short name” for the domain. For example, the name na is returned for the domain na.fabrikam.com.

DomainDNSName

DNS name for the domain (for example, na.fabrikam.com).

ForestDNSName

DNS name for the forest (for example, fabrikam.com).

PDCRoleOwner

Distinguished name of the directory service agent that serves as the primary domain controller (PDC) emulator.

SchemaRoleOwner

Distinguished name of the directory service agent that serves as the schema master.

IsNativeMode

Boolean value that indicates whether the domain is in native mode.

Scripting Steps

Listing 9.1 contains a script that uses ADSystemInfo to return basic information about a computer and computer account. To carry out this task, the script must perform the following steps:

  1. Create an instance of the ADSystemInfo object.

  2. Echo the values of ADSystemInfo attributes such as user name, computer name, and site name.

Example 9.1. Retrieving Basic Computer Information Using ADSystemInfo

 1 Set objSysInfo = CreateObject("ADSystemInfo")
 2 Wscript.Echo "User name: " & objSysInfo.UserName
 3 Wscript.Echo "Computer name: " & objSysInfo.ComputerName
 4 Wscript.Echo "Site name: " & objSysInfo.SiteName
 5 Wscript.Echo "Domain short name: " & objSysInfo.DomainShortName
 6 Wscript.Echo "Domain DNS name: " & objSysInfo.DomainDNSName
 7 Wscript.Echo "Forest DNS name: " & objSysInfo.ForestDNSName
 8 Wscript.Echo "PDC role owner: " & objSysInfo.PDCRoleOwner
 9 Wscript.Echo "Schema role owner: " & objSysInfo.SchemaRoleOwner
10 Wscript.Echo "Domain is in native mode: " & objSysInfo.IsNativeMode

Creating Computer Accounts

For a computer in your organization to have full access to Active Directory resources, it must have a corresponding computer account in Active Directory. Computers that do not have accounts in Active Directory and do not belong to a domain have limited access to resources and cannot be managed by using Group Policy or software installation and maintenance.

Table 9.3 lists the Microsoft Windows operating systems and indicates whether a computer running a given operating system requires a computer account in Active Directory.

Table 9.3. Operating Systems and Computer Account Requirements

Operating System

Computer Account Required

Windows XP Home Edition

 

Windows XP Professional

Windows XP 64-Bit Edition

Windows 2000 Professional

Windows 2000 Server

Windows 2000 Advanced Server

Windows 2000 Datacenter Server

Windows NT Server 4.0

Windows NT Server 4.0, Terminal Server Edition

Windows NT Server 4.0, Enterprise Edition

Windows NT Workstation 4.0

Windows NT Server 3.51

Windows NT Workstation 3.51

Windows Millennium Edition

 

Windows 98

 

Windows 95

 

Windows 3.1

 

Computer accounts can be created programmatically by using ADSI (and, more specifically, by using the IADs interface). To create a large number of computer accounts in a single operation, you can write a script that reads relevant information (computer name, computer location, and so forth) from a text file or a database, and then creates an account for each new computer. Using this kind of script is much quicker than manually creating each computer account by using Active Directory Users and Computers.

Note

Note

For information about reading data from a database, see “Creating Enterprise Scripts” in this book.

When you create a computer account, you need to specify only the common name and the Security Accounts Manager (SAM) account name; the other mandatory attributes are automatically created for you.

However, if you specify only those two items, the account will initially be disabled. For a computer account to be enabled, you must also set the appropriate flags in the userAccountControl attribute. The userAccountControl attribute determines a number of different account attributes, including whether an account is enabled or disabled and whether an account requires a password. By setting two flags (ADS_UF_PASSWD_NOTREQD and ADS_UF_WORKSTATION_TRUST_ACCOUNT), the account will be enabled upon creation.

Setting Flags in the userAccountControl Attribute

For the purposes of this chapter, consider the userAccountControl attribute to be a control panel with a series of switches. These switches can be set to on or off. If a switch is set to on, the attribute controlled by that switch (the flag within the userAccountControl attribute) is also on. For example, if the ADS_UF_WORKSTATION_TRUST_ACCOUNT switch is on, that means that the account is a trusted workstation account. If the switch is off, the account is not a trusted workstation account. For a computer account to be enabled, both the ADS_UF_PASSWD_NOTREQD and ADS_UF_WORKSTATION_TRUST_ACCOUNT switches must be on.

Each flag within the userAccountControl attribute is assigned a value; for example, ADS_UF_PASSWD_NOTREQD is assigned the value &h0020 and ADS_UF_WORKSTATION_TRUST_ACCOUNT is assigned the value &h1000. These values correspond to the switches in the hypothetical control panel. When the userAccountControl attribute is assigned the value &h0020, it effectively flips the switch for ADS_UF_PASSWD_NOTREQD. Likewise, assigning the value &h1000 flips the switch for ADS_UF_WORKSTATION_TRUST_ACCOUNT.

If you are wondering how the userAccountControl attribute can be assigned multiple values, it is because the userAccountControl attribute contains multiple switches (flags).

For a more technical explanation of both the userAccountControl attribute and setting flags within that control, see “Active Directory Users” in this book.

Scripting Steps

Listing 9.2 contains a script that creates a computer account in Active Directory. To carry out this task, the script must perform the following steps:

  1. Create a variable named strComputer, and set the value to the name of the computer account to be created.

  2. Create a constant named ADS_UF_PASSWD_NOTREQD and set the value to &h0020.

  3. Create a constant named ADS_UF_WORKSTATION_TRUST_ACCOUNT and set the value to &h1000.

    These two constants are used to configure flags in the userAccountControl property and enable the new computer account. You can create a computer account merely by specifying a value for the sAMAccountName attribute. In that case, however, the account will be created but will not be enabled, and thus cannot be used immediately.

  4. Bind to the Computers container in Active Directory. The new account will be created in this container. To create the account in an organizational unit (OU), bind to the appropriate OU instead.

  5. Use the Create method to create the new account in the local cache. The Create method requires the following two parameters:

    • “Computer” — indicating the type of account to be created.

    • “cn=” & strComputer — indicating that the cn for the computer should be configured to the value of the variable strComputer.

  6. Use the Put method to set the value of the sAMAccountName attribute to the name of the computer and append a dollar sign ($) (in this case, atl-pro-001$).

  7. Use the Put method to enable the ADS_UF_PASSWD_NOTREQD and ADS_UF_WORKSTATION_TRUST_ACCOUNT flags in the userAccountControl property. This will enable the new computer account.

  8. Use the SetInfo method to apply the changes in the local cache to Active Directory. In turn, this will create the new account.

Example 9.2. Creating a Computer Account in Active Directory

 1 strComputer = "atl-pro-001"
 2 Const ADS_UF_PASSWD_NOTREQD = &h0020
 3 Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &h1000
 4 Set objRootDSE = GetObject("LDAP://rootDSE")
 5 Set objContainer = GetObject("LDAP://cn=Computers," & _
 6     objRootDSE.Get("defaultNamingContext"))
 7 Set objComputer = objContainer.Create("Computer", "cn=" & strComputer)
 8 objComputer.Put "sAMAccountName", strComputer & "$"
 9 objComputer.Put "userAccountControl", _
10     ADS_UF_PASSWD_NOTREQD Or ADS_UF_WORKSTATION_TRUST_ACCOUNT
11 objComputer.SetInfo

Using the New Computer Account

After the account has been created, the computer in question must still be joined to the domain. This can be done only by someone who has the right to join a computer to the domain and who has access rights to the newly created computer account. By default, only administrators have access to the computer account; consequently, only an administrator can join the computer to the domain.

Deleting Computer Accounts

When a computer is no longer used within an organization, you might want to delete its corresponding computer account from Active Directory. Retaining accounts that are not tied to a specific computer can complicate computer management in the following ways:

  • The organization will appear to be responsible for more computers than it actually has.

  • The one-to-one correspondence between the computers listed in the computer inventory and the computer accounts shown in Active Directory will no longer exist.

  • Automated scripts that attempt to run against every computer account in an Active Directory container will encounter problems because the script will try to access computers that no longer exist.

The ADSI IADsDeleteOps interface enables you to programmatically delete computer accounts from Active Directory.

Note

Note

When you programmatically delete a computer account, no confirmation box will appear (although you can write code that displays such a confirmation box before actually carrying out the DeleteObject method). Instead, the account object is deleted as soon as the DeleteObject method is called.

Scripting Steps

Listing 9.3 contains a script that deletes a computer account from Active Directory. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to connect to Workstation4, a computer account located in the Computers container in fabrikam.com.

  2. Use the DeleteObject method with the required parameter (0) to remove the account.

    The value (0) is the only value that can be used as the parameter for the DeleteObject method.

Example 9.3. Deleting a Computer Account

1 set objComputer = GetObject _
2     ("LDAP://CN=Workstation4, CN=Computers, DC=fabrikam, DC=com")
3 objComputer.DeleteObject (0)

Deleting Specified Computer Accounts

If all you need to do is delete a single computer account, it is probably faster — and easier — to delete it by using Active Directory Users and Computers. Creating a script to delete a single computer account is probably more trouble than it is worth; scripts are far more useful when they are used to delete multiple computer accounts based on specified criteria.

For example, your organization might have made the decision to require all computers to use the Windows 2000 operating system. To help ensure compliance with this new requirement, you might give departments a specific period of time in which to complete the upgrade. At the end of that time period, you might then delete the accounts for any computer not running Windows 2000. Deleting these accounts will help prevent users from using an unauthorized operating system to gain access to network resources.

You can delete specified computer accounts by writing a script that:

  1. Searches Active Directory for all computer accounts meeting specified criteria. For example, you can search for all computers running Windows 2000 or Windows NT 4.0.

  2. Returns a recordset consisting of all the computer accounts meeting the criteria.

  3. Individually bind to and delete each account in the recordset.

Scripting Steps

Listing 9.4 contains a script that deletes specified computer accounts from Active Directory. To carry out this task, the script must perform the following steps:

  1. Create a constant named ADS_SCOPE_SUBTREE and set the value to 2.

    This constant is used to specify a search that begins in the Active Directory root and then proceeds to search all the child containers as well.

  2. Create an instance of the Active Directory connection object (ADODB.Connection).

  3. Create an instance of the Active Directory command object (ADODB.Command).

    The command object allows you to issue queries and other database commands through the Active Directory connection.

  4. Set the Provider property of the connection object to the Active Directory provider (ADsDSOObject), the OLE database provider for ADSI.

  5. Set the active connection to the Active Directory connection.

  6. Set the command text for the Active Directory command object to the Structured Query Language (SQL) query that retrieves the specified computer accounts from fabrikam.com.

    In this script, the SQL query is "SELECT distinguishedName, operatingSystemVersion FROM 'LDAP://DC=fabrikam,DC=com' WHERE objectClass='computer' AND operatingSystemversion = '4.0'".

  7. Specify values for page size, time-out, search scope, and caching.

    Although this step is optional, it can improve the performance of your script in a domain with thousands of computers.

  8. Execute the SQL query.

    This query returns a recordset consisting of all the computer accounts for all computers currently running the Windows NT 4.0 operating system.

  9. When the set of computers is returned, use the MoveFirst method to move to the first computer in the recordset.

  10. For each computer in the recordset, set the value of the variable strComputer to the distinguished name for the computer account.

  11. Use a second GetObject call to bind to the computer account. You must individually bind to each account because items in an ActiveX Data Object (ADO) recordset are read-only.

  12. After binding to the individual computer account, use the DeleteObject method to delete the account from Active Directory.

Example 9.4. Deleting Specified Computer Accounts

 1 Const ADS_SCOPE_SUBTREE = 2
 2 Set objConnection = CreateObject("ADODB.Connection")
 3 Set objCommand =   CreateObject("ADODB.Command")
 4 objConnection.Provider = "ADsDSOObject"
 5 objConnection.Open "Active Directory Provider"
 6 Set objCommand.ActiveConnection = objConnection
 7 objCommand.CommandText = _
 8     "SELECT distinguishedName, operatingSystemVersion FROM " _
 9         & "'LDAP://DC=fabrikam,DC=com' WHERE objectClass='computer' " _
10             & "AND operatingSystemVersion = '4.0'"
11 objCommand.Properties("Page Size") = 1000
12 objCommand.Properties("Timeout") = 30
13 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
14 objCommand.Properties("Cache Results") = False
15 Set objRecordSet = objCommand.Execute
16 objRecordSet.MoveFirst
17 Do Until objRecordSet.EOF
18     strComputer = objRecordSet.Fields("distinguishedName").Value
19     Set objComputer = GetObject("LDAP://" & strComputer & "")
20     objComputer.DeleteObject (0)
21     objRecordSet.MoveNext
22 Loop

Modifying Computer Accounts

Computer account attributes often need to be modified. For example, because many computer accounts are created before the computers are actually assigned to users, attributes such as Description, Department, and Location cannot be configured at the time the account is created. In addition, the ownership of a computer can be transferred to a new user or department, or a computer might be physically moved to a new location. In such circumstances, the computer account attributes need to be modified.

You can use the ADSI Put and SetInfo methods to modify these attributes at any time. In addition to modifying account attributes, you can also create scripts that:

  1. Rename computer accounts.

  2. Move computer accounts to new Active Directory containers.

  3. Reset computer account passwords.

Enumerating Computer Account Attributes

By retrieving and reviewing computer account attributes you can do such things as identify the computers owned by each department, or compile a list of the computers that are located in a particular location (city, building, floor, room). This information is very useful in a number of situations, from planning new equipment allocations to making preparations to move a group of users from one building to another.

You can use the ADSI IADs Get method to retrieve the attributes of any computer account in Active Directory. You simply bind to the appropriate computer account and then echo the value of the desired attributes.

Creating a script to return computer account attributes is easy, but there is one caveat you must be aware of. Although you can retrieve any attribute by using ADSI, a problem can occur if any of these attributes have a null value (that is, if no value has been assigned to the attribute). For example, suppose you create a computer account and assign values only to the mandatory attributes. In that instance, all the optional attributes, including such properties as Location and Description, will have a null value, which means no value has been assigned to the attribute.

Although a script can retrieve attributes with null values, an error will occur if you attempt to do things such as assign that value to a variable or echo the value to the screen. For example, if you attempt to report the value, you will receive the following error message:

The property could not be found in the cache.

To avoid getting this error, your script must do two things:

  1. Include the On Error Resume Next statement at the beginning of the script. This will prevent the script from failing if an attribute has a null value.

  2. Check each retrieved attribute to ensure that the value is not null before attempting to do anything else with it. For example, before echoing the value of the computer account Location attribute, check to ensure that the computer actually has a location.

You can check for null values by using the function IsNull in Microsoft® Visual Basic® Scripting Edition (VBScript). The following code sample tests to see if the value assigned to the variable strLocation is null. If it is, a message is echoed.

If IsNull(strLocation) Then
    Wscript.Echo "The location has not been configured for this computer."
Else
    Wscript.Echo "Location: " & strLocation
End If

Scripting Steps

Listing 9.5 contains a script that enumerates the values of two attributes of a computer account. To carry out this task, the script must perform the following steps:

  1. Include the On Error Resume Next statement. This will prevent the script from failing if the value of either the Location or Description attribute is null.

  2. Use a GetObject call to bind to the computer account.

  3. Use the Get method to retrieve the computer location.

  4. Use the IsNull function to check whether a value has been configured for the Location attribute, and do one of the following:

    • If no location has been configured, echo a message stating that the Location attribute has not been configured.

    • If a location has been configured, echo the value of the Location attribute.

  5. To retrieve the computer description, repeat steps 2 and 3, using the Get method to retrieve the Description attribute and then echoing the value of that attribute. If the value is null, echo the message “The description has not been configured for this computer.”

This same approach can be used to retrieve additional computer account attributes.

Example 9.5. Enumerating Computer Account Attributes

 1 On Error Resume Next
 2 Set objComputer = GetObject _
 3     ("LDAP://CN=atl-dc-01, CN=Computers, DC=fabrikam, DC=com")
 4 objProperty = objComputer.Get("Location")
 5 If IsNull(objProperty) Then
 6     Wscript.Echo "The location has not been set for this computer."
 7 Else
 8     Wscript.Echo "Location: " & objProperty
 9     objProperty = Null
10 End If
11 objProperty = objComputer.Get("Description")
12 If IsNull(objProperty) Then
13     Wscript.Echo "The description has not been set for this computer."
14 Else
15     Wscript.Echo "Description: " & objProperty
16     objProperty = Null
17 End If

Configuring the Computer Account Location Attribute

The computer account Location attribute is crucial for administrative tasks that depend on knowing the physical location of individual or multiple computers. For example, knowing the physical location of individual computers enables you to dispatch service technicians to those computers. If a computer is no longer accessible over the network, you can use the Location attribute for the computer account to determine the actual physical location of the computer.

Location information can also help in identifying and diagnosing problems across the network. For example, if you observe that four computers having similar problems are located in the same general area, you might speculate that the problem is not with the computers themselves, but with the network infrastructure.

In addition, configuring the location for a computer allows you to use Active Directory printer location tracking. Printer location tracking enables users to quickly locate printers in their immediate proximity. To enable printer location tracking, you must develop a domain-wide naming scheme and use that scheme to specify the locations of all your printers and all your computers.

For more information about Active Directory printer location tracking, see “Printing” in this book.

You can use ADSI to configure the Location attribute for a computer account. Although the Location attribute for an individual computer can be easily changed by using Active Directory Users and Computers, scripts can be particularly useful if a large group of computers changes location at the same time (for example, when an entire department moves from one building to another).

Scripting Steps

Listing 9.6 contains a script that changes the value of the Location attribute for a computer. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to bind to the desired computer.

  2. Use the Put method to set the value of the Location attribute to Building 37, Floor 2, Room 2133.

  3. Use the SetInfo method to write the changes to the computer account.

Example 9.6. Changing the Computer Account Location Attribute

1 Set objComputer = GetObject _
2     ("LDAP://CN=atl-dc-01, CN=Computers, DC=fabrikam, DC=com")
3 objComputer.Put "Location" , "Building 37, Floor 2, Room 2133"
4 objComputer.SetInfo

Renaming Computer Accounts

If you rename a computer for any reason, you must also rename the computer account. Although it is generally best to rename both the computer and the computer account at the same time, this is not always possible. For example, a computer might be transferred to a new department and thus need be renamed to reflect departmental standards. If the new user does not have the right to rename the computer account in Active Directory, however, a discrepancy will exist between the computer name and the computer account name. This is not an unusual scenario; many organizations place strict limits on the modifications users can make to any object stored in Active Directory.

In a situation such as this, a person with the right to rename the computer account will have to rename the computer account to match the new computer name.

You can rename a computer account by using the ADSI MoveHere method. Using the MoveHere method, the script binds to a computer account and then moves the account. Rather than moving the account to a new OU or another new container, however, the script leaves the account in the same OU, but “moves” it to a new account name.

For example, to rename a computer account named ComputerA in the Finance OU, you “move” the computer account to a new account named ComputerB, also located in the Finance OU. This has the same effect as renaming the account. The account named ComputerA disappears, and the information previously stored in that account is now stored in the new account named ComputerB.

Scripting Steps

Listing 9.7 contains a script that renames a computer account. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to bind to the Active Directory container in which the computer account is stored.

  2. Use the MoveHere method with the following two parameters:

    • The object to be renamed (“LDAP://CN=Workstation4, OU=Finance, DC=fabrikam, DC=com”).

    • The new common name for the object (“CN=Workstation5”).

Example 9.7. Renaming a Computer Account

1 Set objNewOU = GetObject("LDAP://OU=Finance, DC=fabrikam, DC=com")
2 Set objMoveComputer = objNewOU.MoveHere _
3     ("LDAP://CN=Workstation4, OU=Finance, DC=fabrikam, DC=com", _
4         "CN=Workstation5")

When this script is run, the computer account Workstation4 is renamed to Workstation5. The account remains in the Finance OU.

Moving Computer Accounts

Occasionally it is necessary to move computer accounts to reflect changes in organizational or managerial structure, to account for a transfer of equipment ownership, or to facilitate the application of Group Policy.

For example, many organizations place all new computer accounts in the Computers container in Active Directory. However, having all the computer accounts in the Computers container makes it difficult to know which computers belong to which departments. In addition, Group Policy cannot be applied to the Computers container because it is not an OU. Keeping all computer accounts in the same container also limits your ability to delegate administrative control of those accounts. If all computer accounts are stored in the Computers container, you cannot give the Finance Department system administrator control over accounts in his department without also giving that administrator control over all the accounts in that container.

For these reasons, computer accounts are typically moved out of the Computers container as soon as the computers are given to particular users or departments. Moving accounts to the appropriate Active Directory OU helps reflect the actual distribution of resources within the organization and allows for delegation of administration. For example, the Finance Department can use one set of policies to manage their computers, while the Human Resources Department can use a separate set of policies to manage their computers.

Accounts can be moved from one Active Directory container to another programmatically by using ADSI.

Scripting Steps

Listing 9.8 contains a script that moves a computer account to a different OU. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to bind to the Active Directory container to which the computer account will be moved. In this example, the container is the Finance OU in fabrikam.com.

    This first step illustrates one important difference between renaming a computer account and moving a computer account: When you rename a computer account, you bind to the Active Directory container in which the account currently resides. When you move a computer account, you bind to the container to which the account will be moved.

  2. Use the MoveHere method with the following two parameters:

    • Distinguished name of the account to be moved (LDAP://CN=Server4, CN=Computers, DC=fabrikam, DC=com).

    • Common name to be given to the account in the new container. Keeping the common name the same (CN=Workstation4) ensures that the account will be moved without being renamed.

Example 9.8. Moving Computer Accounts

1 Set objNewOU = GetObject("LDAP://OU=Finance, DC=fabrikam, DC=com")
2 Set objMoveComputer = objNewOU.MoveHere _
3     ("LDAP://CN=Workstation4, CN=Computers, DC=fabrikam, DC=com", _
4         "CN=Workstation4")

Resetting Computer Account Passwords

Each computer account has a password that must match a password stored in Active Directory. If the two passwords do not match, Active Directory cannot authenticate the computer. If this occurs, the computer account password must be reset by a system administrator. Resetting the password returns both the password stored on the computer and the password stored in Active Directory to the default value, and enables the computer to be authenticated.

When a computer account is created, the passwords for both the account and the secure channel (a special communication channel used to communicate with a domain controller) are set to %computername%$. For example, a new computer named Server7 would be given an initial password of Server7$. After the computer has joined the domain, a unique password is generated to replace %computername%$. Thereafter, a new password for both the computer account and the secure channel is automatically generated every 30 days.

Although these passwords generally match, certain situations can cause them to differ. For example, Active Directory replication problems might cause one of the passwords to be changed but not the other one. Or, a computer might be offline for an extended period of time. During that time, the Active Directory password might have been changed; with the computer offline, however, the local password could not have been changed accordingly. In either case, Active Directory would be unable to authenticate the computer and the user unable to log on to the network. Instead, a user attempting to log on would be presented with the following error message:

The session setup from the computer DomainMember failed to authenticate. The name
of the account referenced in the security database is DomainMember$. The
following error occurred: Access is denied.

If this occurs, a system administrator must reset the password for the computer account, which can be done using the ADSI IADsUser interface.

Scripting Steps

Listing 9.9 contains a script that resets a computer account password. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to bind to the computer account in Active Directory.

  2. Use the SetPassword method to reset the password to the original computer password: the computer name, with a dollar sign ($) appended to it.

Example 9.9. Resetting a Computer Account Password

1 Set objComputer = GetObject _
2     ("LDAP://CN=atl-dc-01,CN=Computers,DC=fabrikam,DC=COM")
3 objComputer.SetPassword "atl-dc-01$"

Searching for Computer Accounts in Active Directory

Active Directory is more than a repository for resources such as accounts, shared printers, and public folders. It is also a searchable database that allows users and administrators to quickly locate these resources. Because computer accounts are stored in Active Directory, you can take advantage of the Active Directory searching capabilities to locate any computer in your organization.

Active Directory supports the following two primary search types:

  • Basic enumeration. Lists all the computer accounts in a specified domain, OU, or other Active Directory container. For example, a SQL command similar to the following retrieves a list of all the computers in fabrikam.com:

    Select Name from 'LDAP://DC=fabrikam,DC=com' where objectClass = 'computer'
    
  • Filtered search. Returns only the computer accounts that have a specified value for an attribute. For example, you might search for all computers located in a particular building or owned by a particular department. The following SQL command retrieves all the computers owned by the Finance Department:

    Select Name from 'LDAP://DC=fabrikam,DC=com' where objectClass='computer'
    and Department = 'Finance'
    

The filtered search capabilities of Active Directory allow you to write scripts that can run against a specified set of computers even if you do not know the names of those computers. For example, if the Human Resources department moves to a new building, you can retrieve a list of computers for which the value of the Department attribute is equal to Human Resources, and then change the value of the Location attribute. Likewise, you can search Active Directory for a list of all the domain controllers in the domain and then run a monitoring or inventory script against those computers.

When you conduct a search, a recordset is returned that includes each of the computers that meet the search criteria. For more information about working with recordsets, see “Creating Enterprise Scripts” in this book.

Facilitating a Search in Active Directory

Following are some tips that can facilitate Active Directory searches. For more information about searching in Active Directory, see “ADSI Scripting Primer” in this book.

Target the scope of the search appropriately.

Large Active Directory domains can contain thousands of computers. Instead of searching through all of Active Directory to find the computers of interest, search only the container in which the computer accounts are likely to be stored (for example, in the Finance OU).

Set a search page size.

Some searches can returns thousands of objects. A return of the entire recordset in one operation can noticeably degrade the performance of the server, the client, and the network. If you expect your search to return a large number of objects, specify a search page size to allow the server to return information in more manageable chunks. For example, rather than return 50,000 records all at once, a search with a page size of 500 allows the computer to return just the first 500 records when the search is completed, and each subsequent set of 500 records only when requested.

Include a time-out value.

When you conduct a search of Active Directory, your search request is queued and the server attempts to satisfy the request as soon as possible. If the server is extremely busy, the request can be delayed or the search can be slow. You can specify a time-out value to make the script wait a set amount of time (for example, 30 seconds) for a reply from the server, and then automatically terminates if no reply is received.

Limit the number of attributes retrieved.

If you need only the common name for each computer, do not retrieve the entire set of attributes. Scripts returning fewer attributes run faster and minimize the amount of data that must be transmitted across the network.

Use a search filter.

Instead of returning a list of all the computers, return only the computers that meet specific criteria (for example, only the computers located in a particular building or only the computers with a particular version of the operating system installed).

Enumerating All the Computer Accounts in Active Directory

All computers running Windows NT, Windows 2000, and Windows XP Professional in a domain must have accounts in Active Directory. Because of this, Active Directory contains a list of all the computers in your organization that run one of these operating systems. Any time you need such a list (perhaps for inventory or planning purposes), you can retrieve this information by using ADSI to enumerate all the computer accounts in Active Directory.

Note

Note

In large organizations, Active Directory can contain thousands of computer accounts. Any operation that attempts to enumerate all the accounts can take a considerable amount of time to be completed. Because of that, you might want to conduct large searches at a time when user and network activity is low.

Scripting Steps

Listing 9.10 contains a script that enumerates all the computer accounts in Active Directory. To carry out this task, the script must perform the following steps:

  1. Create a constant named ADS_SCOPE_SUBTREE and set the value to 2.

    This constant is used to specify a search that begins in the Active Directory root and then proceeds to search all the child containers as well.

  2. Create an instance of the Active Directory connection object (ADODB.Connection).

  3. Create an instance of the Active Directory command object (ADODB.Command).

    The command object allows you to issue queries and other database commands through the Active Directory connection.

  4. Set the Provider property of the connection object to the Active Directory provider (ADsDSOObject), the OLE database provider for ADSI.

  5. Set the active connection to the Active Directory connection.

  6. Set the command text for the Active Directory command object to the SQL query that retrieves all the computers from fabrikam.com.

    In this script, the SQL query is "Select Name, Location from 'LDAP://DC=fabrikam,DC=com' where objectClass='computer'".

  7. Specify values for page size, time-out, search scope, and caching.

    Although this step is optional, it can improve the performance of your script in a domain with thousands of computers.

  8. Execute the SQL query.

    This query returns a recordset consisting of all the computer accounts in Active Directory.

  9. When the set of computers is returned, use the MoveFirst method to move to the first computer in the recordset.

  10. For each computer in the recordset, echo the computer name and location.

Example 9.10. Enumerating All the Computer Accounts in Active Directory

 1 Const ADS_SCOPE_SUBTREE = 2
 2 Set objConnection = CreateObject("ADODB.Connection")
 3 Set objCommand =   CreateObject("ADODB.Command")
 4 objConnection.Provider = "ADsDSOObject"
 5 objConnection.Open "Active Directory Provider
 6 Set objCommand.ActiveConnection = objConnection
 7 objCommand.CommandText = _
 8     "SELECT Name, Location FROM 'LDAP://DC=fabrikam,DC=com' " _
 9         & "WHERE objectClass='computer'"
10 objCommand.Properties("Page Size") = 1000
11 objCommand.Properties("Timeout") = 30
12 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
13 objCommand.Properties("Cache Results") = False
14 Set objRecordSet = objCommand.Execute
15 objRecordSet.MoveFirst
16 Do Until objRecordSet.EOF
17     Wscript.Echo "Computer Name: " & objRecordSet.Fields("Name").Value
18     Wscript.Echo "Location: " & objRecordSet.Fields("Location").Value
19     objRecordSet.MoveNext
20 Loop

Locating Computer Accounts Based on Their Attributes

There are times when you need a list of specific computer accounts rather than a list of all the computer accounts in Active Directory. For example, you might want a list of all the computers located in a particular building, all the computers running a specific version of the Windows operating system, or all the computers whose computer accounts have been created in the past 30 days.

To obtain such a list, you can use a filtered search. Because each computer account has a number of attributes associated with it, you can create a search that returns only the computer accounts for which specific attributes meet specific criteria.

For example, the Department property is an attribute of the computer account. To return a list of all the computers that belong to a specific department, you can create a query that limits data retrieval only to those accounts for which the attribute value is equal to a specific value (for example, Department = “Finance”). For a list of attributes to use for searching, see Table 9.1.

Note

Note

Most computer account attributes, such as Department, are optional and do not require values to be specified at the time the computer account is created. However, in order for you to be able to search by using a specific attribute, the desired accounts must have a value for that attribute. If you do not require administrators to specify the department when creating a computer account, you will have no way to search for computers based on the Department attribute. To avoid this problem, you can design a script that creates an account only if a complete set of values is assigned to the attributes.

Scripting Steps

Listing 9.11 contains a script that locates computers based on computer account attributes. To carry out this task, the script must perform the following steps:

  1. Create a constant named ADS_SCOPE_SUBTREE and set the value to 2.

    This constant is used to specify a search that begins in the Active Directory root and then proceeds to search all the child containers as well.

  2. Create an instance of the Active Directory connection object (ADODB.Connection).

  3. Create an instance of the Active Directory command object (ADODB.Command).

    The command object allows you to issue queries and other database commands through the Active Directory connection.

  4. Set the Provider property of the connection object to the Active Directory provider (ADsDSOObject), the OLE database provider for ADSI.

  5. Set the active connection to the Active Directory connection.

  6. Set the command text for the Active Directory command object to the SQL query that retrieves all the computers from fabrikam.com.

    To limit the number of computers retrieved, an additional clause is included that limits the search to computers that have a value of 5.0 (2195) for their operatingSystemVersion attributes. This is the version number for Windows 2000.

  7. Specify values for page size, time-out, search scope, and caching.

    Although optional, this step can improve the performance of your script in a domain with thousands of computer accounts.

  8. Execute the SQL query.

    This query returns a collection of all the computers in Active Directory with an operating system of version 5.0 (2195).

  9. When the set of computers is returned, use the MoveFirst method to move to the first computer in the recordset.

  10. For each computer in the recordset, echo the computer name and location.

Example 9.11. Locating Computers Based on Computer Account Attributes

 1 Const ADS_SCOPE_SUBTREE = 2
 2 Set objConnection = CreateObject("ADODB.Connection")
 3 Set objCommand =   CreateObject("ADODB.Command")
 4 objConnection.Provider = "ADsDSOObject"
 5 objConnection.Open "Active Directory Provider"
 6 Set objCommand.ActiveConnection = objConnection
 7 objCommand.CommandText = _
 8     "SELECT Name, Location, operatingSystemVersion FROM " _
 9         & "'LDAP://DC=fabrikam,DC=com' WHERE objectClass='computer' " _
10             & "and operatingSystemVersion = '5.0 (2195)'"
11 objCommand.Properties("Page Size") = 1000
12 objCommand.Properties("Timeout") = 30
13 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
14 objCommand.Properties("Cache Results") = False
15 Set objRecordSet = objCommand.Execute
16 objRecordSet.MoveFirst
17 Do Until objRecordSet.EOF
18     Wscript.Echo "Computer Name: " & objRecordSet.Fields("Name").Value
19     Wscript.Echo "Location: " & objRecordSet.Fields("Location").Value
20     objRecordSet.MoveNext
21 Loop

Managing Computer Roles

One of the primary goals of system administrators is to continually reduce the need for system administration. For example, system administrators could manually edit host files, thus enabling users to access resources over the intranet and the Internet. Alternatively, system administrators can use DNS and allow computers to carry out this task. System administrators could visit each individual computer in the organization and use a known user name and password to log users on the network; alternatively, they can rely on Active Directory and allow domain controllers to authenticate users.

What this means, of course, is that computers are dynamic role players largely responsible for keeping a network functioning. This also means that all computers are not alike: some are workstations, some are member servers, and some are domain controllers. Others take on additional roles; these computers might be responsible for key services such as DNS or DHCP, or they might hold important Active Directory roles such as global catalog server or PDC emulator. Scripting provides a way for you to identify the various roles played by a computer, and also allows you to change those roles as needed.

Identifying Computer Roles

It is important to know whether a computer is part of a domain because this helps determine the means by which a computer can be managed. Computers that do not belong to a domain and do not have accounts in Active Directory cannot be managed by using Group Policy or software installation and maintenance.

For example, a single domain-level Group Policy can be applied to computers that are members of a domain. Stand-alone computers, by contrast, must be managed on an individual basis by using local Group Policy. Domain membership also affects the availability of resources for anyone using that computer.

The role that a computer plays within a domain (workstation, server, or domain controller) also impacts the management of that computer. For example, when you use scripts that automatically install software or configure a computer, you need to know the computer role because:

  • Some software is designed for installation on workstations but not on servers.

  • Some services need to be configured by using a particular service account if they are being installed on a member server, but not if they are being installed on a domain controller.

  • Some software installation programs might automatically reboot the computer, and you might prefer that certain computers not be taken offline.

In these instances, verifying a computer’s role before you install software or configure a service helps ensure that you install the correct software on the computer or use the correct service account for the role of the computer.

The DomainRole property of the Win32_ComputerSystem class can be used to identify the basic role of a computer and its membership in a domain. This property returns one of the values shown in Table 9.4.

Table 9.4. DomainRole Property Values

Value

Description

0

Stand-alone workstation (the computer is not a member of a domain)

1

Member workstation

2

Stand-alone server (the computer is not a member of a domain)

3

Member server

4

Backup domain controller

5

Primary domain controller

Scripting Steps

Listing 9.12 contains a script that identifies the basic role of a computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2 on the computer, and set the impersonation level to Impersonate.

  3. Use the ExecQuery method to query the Win32_ComputerSystem class.

  4. Retrieve the value of the DomainRole property.

  5. Convert the value of the DomainRole property to a string value, and then echo that result.

    This step is required because the DomainRole property is stored as an integer (for example, the value 0 for the DomainRole property means that the computer is a stand-alone workstation). This step converts the integer to the appropriate string value.

Example 9.12. Identifying the Basic Role of a Computer

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colComputers = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_ComputerSystem")
 6 For Each objComputer in colComputers
 7     Select Case objComputer.DomainRole
 8         Case 0
 9             strComputerRole = "Standalone Workstation"
10         Case 1
11             strComputerRole = "Member Workstation"
12         Case 2
13             strComputerRole = "Standalone Server"
14         Case 3
15             strComputerRole = "Member Server"
16         Case 4
17             strComputerRole = "Backup Domain Controller"
18         Case 5
19             strComputerRole = "Primary Domain Controller"
20     End Select
21     Wscript.Echo strComputerRole
22 Next

Identifying the Role of a Computer Based on the Service It Provides

The way in which you manage a specific computer depends greatly on the role that computer plays. For example, you generally monitor different aspects of a DNS server than a DHCP server. Although no single property can tell you whether a particular computer is a database server, an e-mail server, or a multimedia server, you can often identify the role a computer plays by identifying the services installed on it.

In large organizations, only one of the major services (such as e-mail) is likely to be installed on a single computer. It would be unusual for a mail server to also perform as a server for Microsoft® Windows Media® technologies player files. Because of this, identifying a service installed on a computer can help identify the computer’s role in the network. If the Microsoft® Exchange Server service is installed and running on a computer, it is generally safe to assume that this computer functions as a mail server.

You can use the WMI Win32_Service class to enumerate the services installed on a computer. In addition, you can use this class to determine whether those services are currently running and to return any other required information about that service and how it has been configured.

Note

Note

For more information about managing services using WMI, see “Services” in this book.

Scripting Steps

Listing 9.13 contains a script that identifies computer roles based on services installed on the computer. To carry out this task, the script must perform the following steps:

  1. Create a variable to specify the computer name.

  2. Use a GetObject call to connect to the WMI namespace rootcimv2 on the computer, and set the impersonation level to Impersonate.

  3. Use the ExecQuery method to query the Win32_Service class.

    To limit the number of services returned, a Where clause is used to restrict data retrieval to those services with a registry name of MSSQLServer.

  4. Use the Count property to determine the number of services returned.

    The Count property provides a quick way to determine whether any instances of Microsoft® SQL Server™ are installed on the computer. If the value of the Count property is 0, SQL Server is not installed. If the Count is greater than 0, SQL Server is installed.

  5. Based on the value of the Count property, echo a string reporting whether SQL Server is installed.

    If the service is installed, the script also echoes the current service state, that is, whether the service is running, paused, stopped, or resuming operation.

Example 9.13. Identifying Computer Roles Based on Services

 1 strComputer = "."
 2 Set objWMIService = GetObject("winmgmts:" _
 3     & "{impersonationLevel=impersonate}!\" & strComputer & "
ootcimv2")
 4 Set colServices = objWMIService.ExecQuery _
 5     ("SELECT * FROM Win32_Service WHERE Name = 'MSSQLServer'")
 6 If colServices.Count > 0 Then
 7     For Each objService in colServices
 8         Wscript.Echo "SQL Server is " & objService.State & "."
 9     Next
10 Else
11     Wscript.Echo "SQL Server is not installed on this computer."
12 End If

Identifying Active Directory–Specific Roles

Several computer roles (available only to domain controllers) are contingent upon membership in an Active Directory domain, including the operations master roles (also known as flexible single master operations, or FSMO, roles) and the global catalog server role. Because Active Directory relies on these roles to carry out operations, it is vital for system administrators to know which computers perform operations master roles or function as global catalog servers.

You can use ADSI to determine the Active Directory roles played by a given computer. Depending on your needs, you can do this by searching Active Directory for computers that perform specific roles or by using ADSI to bind to a computer and enumerate the roles that the computer performs.

Enumerating Domain Controllers

The script shown in Listing 9.12 can connect to a specified computer and tell you whether that computer is a domain controller. What the script cannot do, however, is tell which other computers are domain controllers. To do that, the script would need to connect to every computer and determine the computer role.

A better way to obtain a list of all your domain controllers is to retrieve that information from Active Directory. Active Directory includes a Configuration partition that maintains information about the structure of the directory service. This information includes such things as the names of all the domains in the forest and the names of all the domain controllers and global catalog servers. To retrieve a list of domain controllers, you can search the Configuration container for all instances of the nTDSDSA object class. This class represents the Directory Services Agent, the process that provides access to the Active Directory database itself. All domain controllers are members of this class.

Scripting Steps

Listing 9.14 contains a script that enumerates all the domain controllers in Active Directory. To carry out this task, the script must perform the following steps:

  1. Create a constant named ADS_SCOPE_SUBTREE and set the value to 2.

    This constant is used to specify a search that begins in the Active Directory root and then proceeds to search all the child containers as well.

  2. Create an instance of the Active Directory connection object (ADODB.Connection).

  3. Create an instance of the Active Directory command object (ADODB.Command).

    The command object allows you to issue queries and other database commands through the Active Directory connection.

  4. Set the Provider property of the connection object to the Active Directory provider (ADsDSOObject), which is the OLE database provider for ADSI.

  5. Set the active connection to the Active Directory connection.

  6. Set the command text for the Active Directory command object to the SQL query that retrieves all the domain controllers from fabrikam.com.

    The SQL query that retrieves the list of domain controllers is Select distinguishedName from ' LDAP://cn=Configuration,DC=fabrikam,DC=com' where objectClass='nTDSDSA.

  7. Specify values for page size, time-out, search scope, and caching.

    Although optional, specifying these values can improve the performance of your script in a domain with thousands of computer accounts.

  8. Execute the SQL query.

  9. When the set of domain controllers is returned, use the MoveFirst method to move to the first computer in the recordset.

  10. For each domain controller in the recordset, echo the computer name.

Example 9.14. Enumerating Domain Controllers

 1 Const ADS_SCOPE_SUBTREE = 2
 2 Set objConnection = CreateObject("ADODB.Connection")
 3 Set objCommand = CreateObject("ADODB.Command")
 4 objConnection.Provider = "ADsDSOObject"
 5 objConnection.Open "Active Directory Provider"
 6 Set objCommand.ActiveConnection = objConnection
 7 objCommand.CommandText = _
 8     "SELECT distinguishedName FROM " _
 9         & "'LDAP://cn=Configuration,DC=fabrikam,DC=com' " _
10             & "WHERE objectClass='nTDSDSA'"
11 objCommand.Properties("Page Size") = 1000
12 objCommand.Properties("Timeout") = 30
13 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
14 objCommand.Properties("Cache Results") = False
15 Set objRecordSet = objCommand.Execute
16 objRecordSet.MoveFirst
17 Do Until objRecordSet.EOF
18     Wscript.Echo "Computer Name: " & _
19         objRecordSet.Fields("distinguishedName").Value
20     objRecordSet.MoveNext
21 Loop

Identifying the Current Domain Controller for a Computer

There are often times when it is useful to know which domain controller was used to authenticate a computer. For example, if users are having difficulty accessing resources, you might want to identify the domain controller that processed the initial authentication. If it seems to be taking an inordinately long time for certain users to log on to the network, you might want to check and see if the same domain controller is processing those logons. To periodically check the validity of your Active Directory topology, you might want to see which domain controllers are being used by the computers at a particular site.

To identify the domain controller used to authenticate a computer, you can use the LDAP provider and bind to rootDSE. When you bind to rootDSE, you are bound to the directory service root. This is why rootDSE is often used as a way to bind to the domain; you can bind to your domain without having to hard-code the domain name within a script.

However, rootDSE is also used to return information about the directory server itself. For example, the dnsHostName attribute tells you the name of the current domain controller for the computer. The serverName attribute returns the distinguished name of the current domain controller.

This script must be run locally; you cannot use it to identify the domain controller for a remote computer. If you want to monitor the domain controllers being used to authenticate user logons, you could use this code as part of a logon script. That way, each time a user logs on, information about the user and the domain controller could be stored in a database.

Scripting Steps

Listing 9.15 contains a script that identifies the current domain controller for a computer. To carry out this task, the script must perform the following steps:

  1. Use the LDAP provider to bind to the Active Directory root.

  2. Use the Get method to retrieve the value of the dnsHostName attribute, and store that value in a variable named objDC.

  3. Echo the value of the variable objDC.

Example 9.15. Identifying the Current Domain Controller

1 Set objDomain = GetObject("LDAP://RootDSE")
2 objDC = objDomain.Get("dnsHostName")
3 Wscript.Echo objDC

Identifying Operations Master Roles

Active Directory includes five operations master roles (also known as flexible single master operation or FSMO) that delegate particular responsibilities to particular computers.

Understanding operations master roles and knowing which computers hold these roles is very important. If an operations master role holder is unavailable, you cannot carry out certain Active Directory activities. For example, in order to modify the schema, the schema master must be available. To know if the schema master is available, you need to know which computer holds this role.

In addition, before you assign a computer certain roles, you need to determine whether that computer holds a conflicting role. For example, in a multidomain forest, the infrastructure master must never be placed on a global catalog server. If a given domain controller is the infrastructure master, you must not promote that domain controller to a global catalog server.

To help identify operations master role holders, you can use the searching capabilities available through ADSI. The five operations master roles and their associated ADSI object class are listed in Table 9.5. The object classes are used to search Active Directory for the operations master role holder. The search connects to the object class and then retrieves the value of the FSMORoleOwner attribute.

Table 9.5. ADSI Object Classes and Operations Master Roles

ADSI Object Class

Operations Master Role

domainDNS

Primary domain controller (PDC) emulator. Serves two essential functions. First, it acts as a primary domain controller to provide compatibility with Windows NT domains. Second, password changes performed within a domain are replicated immediately to the PDC emulator. This ensures that new password changes take effect right away. If a user is unable to log on to a domain due to a password error, the authenticating domain controller contacts the PDC emulator to see if the user’s password has been changed but not yet replicated throughout the domain. If the PDC has a new password, that password is used to authenticate the user.

The PDC emulator is often referred to as the primary domain controller.

rIDManager

RID master. Replenishes the relative IDs (RIDs) for domain controllers.

When a new security principal such as a user or computer account is created, the domain controller used to create the security principal assigns the new object a security identifier (SID). A SID consists of two parts: an identification number that is given to all the objects created in that domain and a unique RID. Together, the two parts uniquely identify any object in the domain.

Each domain controller is allocated 512 RIDs. When a domain controller has approximately 100 RIDs remaining, it contacts the RID master and requests an additional 512 RIDs to replenish its supply. If the RID master is unavailable and a domain controller runs out of relative IDs, you will no longer be able to use that computer to create new Active Directory objects.

infrastructureUpdate

Infrastructure master. Synchronizes group-to-user references.

The infrastructure master is particularly important in a scenario such as this: a user from domain A is a member of a security group in domain B. If you rename the user account, the security group membership is not updated until replication occurs. The infrastructure master is responsible for identifying and correcting issues such as this.

If the infrastructure master fails, you can transfer the role to another domain controller. However, you must ensure that the previous infrastructure master never comes back online.

dMD

Schema master. Updates the schema for the forest. (There is only one schema master per forest.) You must connect to the schema master in order to update the schema.

If the schema master fails, you can transfer the role to another domain controller. However, you must ensure that the previous schema master never comes back online.

crossRefContainer

Domain naming master. Adds or removes a domain from the forest. (There is only one domain naming master per forest.) You cannot add or remove a domain unless the domain naming master is available.

If the domain naming master fails, you can transfer the role to another domain controller. However, you must ensure that the previous domain naming master never comes back online.

Scripting Steps

Listing 9.16 contains a script that identifies operations master roles in Active Directory. To carry out this task, the script must perform the following steps:

  1. Create an instance of the Active Directory connection object (ADODB.Connection).

  2. Set the Provider property of the connection object to the Active Directory provider (ADsDSOObject). This is the OLE database provider for ADSI.

  3. Set the active connection to the Active Directory connection.

  4. Create a command string that searches Active Directory from the root down (LDAP://DC=fabrikam, DC=com). The command string must specify the object class to search for (domainDNS) and the attribute to return (FSMORoleOwner).

    To search for a different operations master role holder, replace domainDNS with the appropriate object class. For example, to locate the RID manager, set the object class to rIDManager.

  5. Execute the search command.

  6. Retrieve the value of the operations master role holder. This value will be returned as a globally unique identifier (GUID).

  7. Connect to the operations master role holder, using the GUID as part of the connection string.

  8. Echo the DNS host name of the operations master role holder.

Example 9.16. Identifying FSMO Roles

 1 Set objADOConnection = CreateObject("ADODB.Connection")
 2 objADOConnection.Provider = "ADSDSOObject"
 3 objADOConnection.Open "ADs Provider"
 4 strADOQueryString = _
 5     "<LDAP://DC=fabrikam,DC=com>;(&(objectClass=domainDNS)" _
 6         & "(fSMORoleOwner=*));adspath;subtree"
 7 Set RSObj = objADOConnection.Execute(strADOQueryString)
 8 Set objFSMO = GetObject(RSObj.Fields(0).Value)
 9 Set objNTDS = GetObject("LDAP://" & objFSMO.fSMORoleOwner)
10 Set objComputer = GetObject(objNTDS.Parent)
11 WScript.Echo "The Primary Domain Controller FSMO is: " & _
12     objComputer.dnsHostName

Identifying Global Catalog Servers

Knowing which computers in your organization are global catalog servers is very helpful for administering Active Directory efficiently.

Because global catalog servers are required for user authentication, it is important to have an adequate number of global catalog servers at a site to handle the volume of authentication requests and a quick connection to handle each request efficiently. If a remote office does not have its own global catalog server and is connected over a slow network link, authentication of the site’s users will be slow.

However, having too many global catalog servers can slow down your network by creating unnecessary replication traffic. Global catalog servers contain information about every item in the forest and can generate a considerable amount of replication data. A remote office that has its own global catalog servers and is connected over a slow network link can provide efficient authentication to its local users, but it might have trouble communicating with other sites because of the quantity of replication data moving across the network link.

You can identify global catalog servers by using ADSI.

Scripting Steps

Listing 9.17 contains a script that identifies global catalog servers by using ADSI. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to bind to the root of the directory information tree on a domain controller (rootDSE).

    The rootDSE is a well-known and reliable location on every domain controller. You can use rootDSE to get distinguished names for the domain container, schema container, and configuration container, as well as other information about the server and the contents of its directory information tree.

  2. Use the Get method to retrieve the value of the dsServiceName attribute.

    This attribute represents the distinguished name of the NTDS Settings object for the directory server.

  3. Use a second GetObject call to connect to the NTDS Settings object.

    The NTDS settings represent the data in Active Directory that define a computer as a domain controller.

  4. Use the Get method to retrieve the value of the Options attribute. The Options attribute represents different things depending on the object. For the NTDS Settings object, the Options attribute indicates whether the computer has been enabled as a global catalog server.

    • If the value is True, echo “This computer is a global catalog server.”

    • If the value is False, echo “This computer is not a global catalog server.”

Example 9.17. Identifying Global Catalog Servers

 1 On Error Resume Next
 2 Set objRoot = GetObject("LDAP://atl-dc-01/RootDSE")
 3 objDSServiceDN = objRoot.Get("dsServiceName")
 4 Set objDSRoot = GetObject("LDAP://atl-dc-02/" & objDSServiceDN )
 5 blnCurrentOptions = objDSRoot.Get("options")
 6 If blnCurrentOptions Then
 7     Wscript.Echo "This computer is a global catalog server."
 8 Else
 9     Wscript.Echo "This computer is not a global catalog server."
10 End If

Enabling or Disabling Global Catalog Servers

As the number of computers in your organization increases or decreases, you might need to enable or disable the global catalog service on domain controllers. For example, if the only global catalog server in a site fails, you can enable a different global catalog server. If a single site has more global catalog servers than it needs (resulting in excessive replication traffic), you can disable the global catalog service on one or more computers.

You can enable and or disable domain controllers as global catalog servers by using ADSI.

Scripting Steps

The scripts for enabling or disabling a global catalog server are very similar.

Enabling a Global Catalog Server

Listing 9.18 contains a script that enables a computer to act as a global catalog server. To carry out this task, the script must perform the following steps:

  1. Use a GetObject call to bind to RootDSE on the domain controller you want to enable as a global catalog server.

  2. Use the Get method to obtain the value of the dsServiceName attribute.

    The dsServiceName attribute represents the distinguished name for the NTDS Settings object for this domain controller.

  3. Use a second GetObject call to connect to the NTDS Settings object.

    The NTDS settings represent the data in the Active Directory that define a computer as a domain controller.

  4. Set the value of the Options attribute to 1.

    The Options attribute represents different things depending on the object. For the NTDS Settings object, the Options attribute indicates whether the computer has been enabled as a global catalog server.

  5. Use the SetInfo method to apply the changes to Active Directory.

Example 9.18. Enabling a Global Catalog Server

1 On Error Resume Next
2 Set objRoot = GetObject("LDAP://atl-dc-01/RootDSE")
3 objDSServiceDN = objRoot.Get("dsServiceName")
4 Set objDSRoot = GetObject("LDAP://atl-dc-01/" & objDSServiceDN )
5 blnCurrentOptions = objDSRoot.Get("Options")
6 objDSRoot.Put "options" , 1
7 objDSRoot.Setinfo

Disabling a Global Catalog Server

To disable a global catalog server, use the same code as shown in Listing 9.18, but set the value of the Options attribute to 0, as shown in Listing 9.19.

Example 9.19. Disabling a Global Catalog Server

1 On Error Resume Next
2 Set objRoot = GetObject("LDAP://atl-dc-01/RootDSE")
3 objDSServiceDN = objRoot.Get("dsServiceName")
4 Set objDSRoot = GetObject("LDAP://atl-dc-01/" & objDSServiceDN )
5 blnCurrentOptions = objDSRoot.Get("Options")
6 objDSRoot.Put "options" , 0
7 objDSRoot.Setinfo
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset