Let users do the work
Many organizations that move to Active Directory (AD) choose to run a new AD domain parallel with their existing Windows NT 4.0 domain. Administrators create the new AD accounts by cloning or copying the NT accounts so that the account name is duplicated (e.g., NT4DOM\NEUBAUER becomes ADDOM\NEUBAUER) and the two accounts have the same password. When I perform these types of migrations, I prefer to disable the AD accounts until they're needed, especially if I create all the accounts at one time, then phase users into the accounts. Disabling the accounts also can help prevent the common "My icons are missing!" migration problem, which I explain in the next section. This migration approach has value, but enabling the accounts later can be a chore. Therefore, I created a scripting solution that can help.
When someone logs on to a workstation, Windows creates a user profile linked to the authenticated account and uses this profile to store user-specific information. For example, if I log on to my workstation with my NT4DOM\NEUBAUER account and configure a network printer, define three persistent drive mappings, and install desktop shortcuts for all my frequently used applications, Windows stores these settings in a user profile linked to my NT4DOM\NEUBAUER account so that the settings are available each time I log on to the workstation. When I log on to the workstation with my new ADDOM\NEUBAUER account, Windows creates a blank profile and links it to the ADDOM\NEUBAUER account. However, the new account profile has none of the customizations that I made while logged on through the NT4DOM\NEUBAUER account.
A good migration plan will include a way to copy the old profile so that its settings are available to the new AD account, making the migration more transparent to the user. A problem in many migrations is that people log on to the workstation with the new account before the profile information has been copied to the new account. When this happens, Windows creates the blank profile and the first thing users notice is that their desktop icons are missing.
By disabling the AD accounts, you can prevent people from logging on until after you finish the profile copy process. However, adopting this strategy creates an additional challenge: how to link the profile-copy process on a specific workstation with a specific user so that you know when to enable the user's new account. I solve this problem by shifting the profile-copy task to the user, then I use an Active Server Pages (ASP) script in a Web page to enable the new account. Through a batch file, such as the one Listing 1 shows, a migrating user runs a tool such as the profile update utility (update.exe) from Quest Software's Quest Migrator. You can deploy the batch file by using a logon script or Microsoft Systems Management Server (SMS) or by having users launch the file from a Web site. When Migrator finishes duplicating the profile, the batch file launches Microsoft Internet Explorer (IE) and opens an ASP Web page on an intranet Web server. The ASP page serves two purposes: First, it tells the user that the account migration is finished. Second, it contains code that accesses AD to enable the user's new account.
ASP Code Details
The script Enable.asp contains the code that the Migration Complete Web page uses to enable a newly migrated account. Listing 2 shows an excerpt from this script. The code at callout A lets you define seven variables for the account you want to enable. The first variable, sLDAPServer, holds the name of an AD domain controller (DC). The script uses authenticated Lightweight Directory Access Protocol (LDAP) queries against this server to enable the account. The next two variables—sObjAccess and sObjKey—hold the username and password, respectively, of the account that will authenticate the script's access to the DC.
As you know, AD lets you create containers called organizational units (OUs) that can hold user account objects. When I migrate accounts, I like to place the new accounts in an OU named Staging. When an account is ready to be used, I enable the account and move it to the Users OU (or the OU it needs to be in to be managed by account administrators). The sStaging- OU and sDestinationOU variables define these containers. After Enable.asp enables an account, the script moves the account from the Staging OU to the destination OU (in this example, the Users OU). From an administrative perspective, this approach is handy because after the migration, any account that remains in the Staging OU probably isn't needed and can be retired. From a security perspective, I like this migration method because the script works only once to enable an account. This approach prevents someone from using the script (or the LDAP authentication account) at some later date to enable a purposefully disabled account.
The last two variables you need to define are sOldDomain and sNewDomain. The sOldDomain variable holds the name of the NT 4.0 domain. When someone opens the Web page, the script retrieves the user's ID from the AUTH_USER server variable, as the code at callout B shows. The ID has two parts—a domain and a user ID—in the format DOMAIN\USERID. The script compares the domain name with the sOldDomain variable's value. When the items match, the script continues to execute; otherwise, the script terminates. The script uses the sNewDomain variable to display the user's new Domain and LAN ID in the Web page, as Figure 1 shows.
The script's overall flow is simple: The script gets the current logon domain and account name from IE and uses that information to build LDAP paths to the various AD containers. Next, as the code at callout C shows, the script uses the credentials defined in the sObjAccess and sObjKey variables to establish an authenticated LDAP session and access the object representing the user account. After changing that object's status to enabled, the script uses the object's SetInfo method to upload the change to AD.
Then, the script uses an authenticated LDAP call to create an object that references the destination (i.e., Users) OU, as the code at callout D shows. The code then calls the object's MoveHere method, which moves the account to its permanent home. The www.winnetmag.com/windowsscripting rest of the script uses response.write statements to generate the Web page that reports the script's success or failure.
In callouts C and D, note the use of the err.number statements. After each operation that involves accessing or manipulating AD, the script tests for an error code. When no error code is returned, the script continues to the next step.
Setting Up AD
Before you use the script, you first need to set up the AD account, OU, and permissions. To do so, open the Microsoft Management Console (MMC) Active Directory Users and Computers snap-in, right-click the Users container, and select New, User from the context menu. Specify the account name (e.g., Migration- Enabler) in the User Logon Name field. To keep things consistent, enter the same name in the Full Name and User Logon Name fields, then click Next. Enter and confirm a password, check the Password Never Expires option, click Next, then click Finish.
To create the Staging OU, right-click the top-level domain name and select New, Organizational Unit from the context menu. Name the OU Staging and click OK. Next, you need to grant administrative rights to a service account so that the service account can modify the account objects that will be in this OU. Right-click the newly created Staging OU and select Delegate Control. When the Delegation of Control Wizard opens, click Next to begin. On the Users or Groups page of the wizard, click Add and type the name of the service account (e.g., Migration- Enabler). Click Check Names to validate your entry, click OK, then click Next. On the wizard's Tasks to Delegate page, select Create a Custom Task to Delegate and click Next. On the Active Directory Object Type page, select Only the following objects in the folder. Scroll through the list of objects and place a check mark next to User objects, then select the Delete selected objects in this folder option and click Next. When the Permissions page opens, select Read All Properties and Write All Properties, as Figure 2 shows. Click Next, then click Finish.
Next, you need to delegate access to the Users container. Right-click the Users container and select Delegate Control. Repeat the same steps you used to delegate access to the Staging OU. However, in the Delegation of Control Wizard's Active Directory Object Type page, instead of selecting Delete selected objects in this folder, select Create selected objects in this folder, as Figure 3 shows. You need to grant delete rights to the Staging OU and grant create rights to the Users OU because the script moves account objects from one OU to another. AD implements a move operation by deleting an object in one container and creating it in another container.
Setting Up IIS
Before running the script, you need to configure your Microsoft Internet Information Services (IIS) 5.0 or later server. You need to create the virtual directory to hold Enable.asp and configure the directory so that it doesn't permit anonymous access. Log on to your IIS server with an account that has local Administrator rights and start the MMC Internet Information Services Manager snap-in. Expand the container tree until you see Default Web Site and right-click it. Select New, Virtual Directory. When the New Virtual Directory Wizard starts, click Next to begin. On the wizard's Virtual Directory Alias page, enter the name Migration and click Next. On the Website Content Directory page, click Browse and select the Inetpub folder. Click Make New Folder and enter Migration as the folder name. Click OK to close the folder browser, then click Next to go to the wizard's next page. Select the Run scripts (such as ASP) check box and clear all other check boxes. Click Next, then click Finish to create the virtual directory. Right-click the Migration virtual directory and select Properties. Select the Directory Security tab, then click Edit in the Authentication and Access Control section. On the Authentication Methods Properties page, clear the Enable anonymous access check box and select the Integrated Windows Authentication check box. Click OK twice to exit the virtual directory's Property pages.
Next you'll need to download Enable.asp from the Windows Scripting Solutions Web site. (Go to http://www .winnetmag.com/windowsscripting, enter 43312 in the InstantDoc ID text box, then click the 43312.zip hotlink.) Place the script in the \Inetpub\Migration folder and modify the seven variables in the code that callout A shows to match your configuration. To test the script, create a disabled user account in the Staging OU and give it the same name as an account in your NT 4.0 domain. Log on as the NT 4.0 account and access the ASP Web page by going to http://yourIISserver.domain.com/ migration/enable.asp, where yourIISserver is the name of your IIS server. If you've configured your settings correctly, you'll receive a confirmation message similar to the one that Figure 1 shows. You can use the Active Directory Users and Computers snap-in to verify that the account is enabled and in the Users OU.
Leverage the Power
Migrations are never simple undertakings. In addition to the array of tedious tasks that every migration entails, you have the complex job of coordinating operations, such as copying profiles on an enterprise full of workstations, with an equally large number of users. You can simplify your life by leveraging the power of scripting so that the user can help with some of these tasks.