As enterprises update their server technology at the hardware or OS level, today's administrators face the tedious task of migrating data between servers. Whether you use large direct-attached storage devices, migrate to a Storage Area Network (SAN) or Network Attached Storage (NAS) technology, or use an Active Directory (AD) deployment that creates new SIDs for all user accounts (thus invalidating existing access control entries—ACEs—in each ACL), storage consolidation and data migration will remain an important part of your job.
Many third-party utilities provide server-consolidation functionality. (For information about these third-party utilities, see Joshua Orrison, "Server Consolidation Software," http://www .win2000mag.com, InstantDoc ID 20652.) However, for large enterprises with many servers to consolidate, the high per-server licensing costs might tip the scale toward building a custom script solution.
To show the advantage of building a solution over buying one, this month I provide the fundamental elements required for using Active Directory Service Interfaces (ADSI) through Windows Script Host (WSH) to develop a scripted data-migration solution. From the Code Library on the Windows Scripting Solutions Web site (http:// www.winscriptingsolutions.com), you can download a functional command-line WSH application called Data-Migration.vbs that demonstrates the concepts I present here. This script is meant not as a complete application but as a starting point for customization. At a minimum, you'll likely want to add error-checking and logging to a file before you use the code in a production environment.
Migrating Data Between Servers
For the sake of simplicity, let's assume that you're moving a user's home directory from one server to another. This example most closely ties in with a storage-consolidation project, such as migration from direct-attached storage to a SAN- or NAS-based device. Although data migration certainly plays an important part in an AD migration, moving a user's home directory would most likely be only one task in a larger operation that potentially includes user-account creation and group migration. Before you can consider the user fully migrated to the new server, you must complete several high-level tasks:
- Identify the source share or directory you want to replicate.
- Determine whether any open files would prevent a proper file-copy operation from finishing (optional).
- Create a new directory on the target server.
- Assign user permissions to the new directory path.
- Copy all data from the user's home directory on the source server to the new directory on the target server.
- Disable the original home-directory share on the source directory, then create a new share on the target server.
- Update the user's profile to reflect the change in profile path.
Identifying the Source and Finding Open Files
For this application, you can migrate data user by user. Assuming that you know the specific user account you want to migrate, you can use ADSI to query the home-directory path for the server name. The GetUserHomeDirectory function that Listing 1 shows is an example of such a query.
However, before you perform a file-copy operation, you must be sure that the share doesn't contain open files. With ADSI, you can use the IADsFileServiceOperations and IADsResource interfaces to enumerate all open files on the server. As the interfaces enumerate the collection, you can look for the target share. If the function finds the target share, the code will skip migration of that share, as Listing 2 shows.
Copying Data and Managing Permissions on the File System
Using the File System Object (FSO), you can create a new directory and copy the files from the source share to the target location. (For more information about FSO, see Dino Esposito, "Understanding VBScript: Working with the File Object," April 2000, and "Understanding VBScript: Manipulating Files with FileSystemObject," January 2000.) To copy the directory content from one share to another, simply use the FSO's CopyFolder method and specify both the source and target pathnames, as the code in Listing 3 shows.
Although the base installation of ADSI doesn't include it, you can use adssecurity.dll from the ADSI software development kit (SDK) to manage file-system permissions. In "Practical Usage of ADSI: Managing User Accounts in Win2K and NT," March 2001, I provided a code segment for establishing a new ACE in an ACL for a user home directory. The downloadable application in the Code Library includes a copy of this code. (For information about using the XCOPY /O command to facilitate data migration, see the sidebar "Using XCOPY /O to Copy Data and ACLs.")
After you've applied permissions to the file system, you can remove the share on the source directory and create a new share on the target machine. To create a share, use the IADsContainer interface to create a new object of class Fileshare in the LanmanServer container, as Listing 4, page 16, shows. To remove the share, use the IADsContainer interface again to remove the named FileShareObject from the LanmanServer container. After you transfer the data, properly apply permissions, and create a new share, you can finish the data-migration effort by using the IADsUser: Home-Directory method to set the user's home-directory path, as Listing 5, page 16, shows.
Running the Data-Migration Solution
Download DataMigration.vbs from the Code Library. To use the code, copy the script to your local workstation. If you haven't already done so, you also need to download a copy of the ADSI SDK from http://www.microsoft.com/adsi and register adssecurity.dll. To execute the basic migration function, use the syntax
CScript DataMigration UserADsPath TargetServer TargetPath CheckForOpenFiles
- UserADsPath is a string representing the ADsPath to a user object
(Valid entries would be similar to WinNT://domain/username,user and LDAP://dc=com/dc=domain/ cn=users/cn=user.)
- TargetServer is a string representing the server to migrate to TargetPath is a string representing the physical path to a directory on the target server (e.g., D:\users\ homedirs)
- CheckForOpenFiles is a Boolean expression that represents whether to check for open files before attempting the File Copy operation
Note that to execute this code successfully, you must have Full Control rights on the file system for both the source and target machines as well as sufficient administrative rights in the user namespace to query the user's home-directory path.
You might need to migrate data between servers because you're installing a new SAN or NAS technology solution, you're incorporating this function as part of an AD user migration, or you simply need to shuffle user home directories between servers. Whatever your reason for migrating data, however, you can use ADSI and WSH to quickly and easily script a solution.