My life as a developer is full of clutter, organised, but nonetheless clutter. I have been developing custom applications for many years and as a consequence I have written client applications which run under a variety of generations of equipment, operating system versions etc. Unlike many developers I do not insist that my clients constantly update their equipment, and I have PC applications in the field that have been running for over 15 years, including applications that still run in DOS. To support these legacy applications and versions I have a number of PC’s configured specifically for them, controlled from KVM switches or running as virtual machines with VMWare. My day to day PC has so many different programs running on it, that alas, it is starting to bog down under its own weight and also its age. So its time now to bring in new hardware and perhaps get rid of some of the old PC’s and create a hive of virtual machines.

To simultaneously run multiple VM’s on the one host requires a degree of “horsepower”, so I invested in a PC with a top of the line CPU, 16Gb RAM running Windows 7 Professional 64bit. This then brings us to the issue of storage and disk drives

Traditional hard disk drives, HDD’s, provide large amounts of storage at low costs but in comparision to the RAM and processors are slow. Data is stored magentically on the surface of one or more coated platters and is directed to the correct place by high speed precision mechanical parts. The magnetic material coated platters rotate at fixed speeds typically 5400RPM, 7200RPM or 10,000RPM, the higher the rotational speed the quicker the access time and lower the latency; so the performance and price is higher but potentially more fragile than slower ones. Typically a 7200RPM has a seek time of about 12milliseconds, latency of about 4milliseconds, and data transfer speeds of about 1000 megabits/sec, they also take some time to spin up from stationery. Because of the way data is stored on a drive there is no guarantee that a file will be contiguously distributed on the drive and files can become very defragmented causing the effective performance of the drive to suffer. Hard Disk Drives are the weakest and slowest link on modern computers

Solid State Drives, SSD’s, on the other hand do not use mechnical mechanisms to store data, but store data in electronic circuits, memory chips etc. So their performance is far better than electromagnetic hard disk drives. Random access time, seek times, and are typically around 0.1ms, with almost instantaneous startup times, and data transfer rates from about 8000 megabits/sec up to about 48,000 megabits/sec. With SSD’s disk fragmentation no longer is a problem and they are silent. In other words – they blow HDD’s away, except for a couple of areas; they are expensive and are only yet available in relatively small capacities.

When Windows and in particular Windows NT first came out it was common to have multiple partitions or even drives in a computer and it was common practice to separate the operating system, programs and data onto different drives to accommodate for system growth. As drive became larger and faster and Windows became more complex it became far more typical to install the operating system, program and data files onto one drive. So much so that now disk drives are so cheap and large Microsoft say there is no need to install Windows onto more than one drive for a desktop PC, and so make no easy provision for doing so.

Microsoft’s logic didn’t factor in that SSD drives would provide such a performance boost and for small drives don’t carry an exorbitant price tag. However for most systems they are just not large enough to totally replace the conventional hard disk drive. In Windows often the thing that is the slowest is it’s start up time, and the loading of operating system components than programs or data, so I decided that I wanted to put the operating system and swap files onto an SSD and move the Programs and Data onto different drives. My inventory of drives included a 120Gb SSD, and a 150Gb 10,000RPM Western Digital Velociraptor drive, a 2Gb drive plus a 1Gb drive, and I had plans for using them all.

The following method will only work with a fresh install, and I have read warnings about how doing something like this might make future upgrading of the Windows installation difficult or impossible, so be warned that you might need to do this all over again one day. It is also probably not supported by Microsoft so you are on your own. Caveat Emptor.

I have read many articles about achieving the result I wanted but I found the following to be the most reliable.

The technique generally involves

  • partially installing Windows 7 onto one drive,
  • switching the installation to Audit Mode,
  • using diskpart to prepare the partitions,
  • using System Preparation Tool, which comes with Windows 7, to create a custom install to install or more accurately reinstall the Users and ProgramData folders on different drive,
  • copy the Program Files folder(s) to a different drive,
  • remove the previously installed Program Files, Users and ProgramData folders from the %systemdrive% and replacing them with symbolic links (junctions) pointing to the new locations for these folders
  • tidying things up

Preparation

Drive Assignments plan

HDD1 C: drive – Operating System and Symbolic links, Solid State Drive 120Gb
HDD2 D: drive – Program Files and Program Data, fast 10,000rpm drive
HHD3 E: drive – Data files Users
CD/DVD F: drive – installation source
HHD4 G: drive – Acronis backups

Preparation for the SysPrep script

The following contents should be saved in a file unattend.xml on a USB stick. (The file name is not strictly important)

[sourcecode language=”xml”] <?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup"
processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35"
language="neutral"
versionScope="nonSxS"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FolderLocations>
<ProfilesDirectory>E:\Users</ProfilesDirectory>
<ProgramData>D:\ProgramData</ProgramData>
</FolderLocations>
</component>
</settings>
<cpi:offlineImage cpi:source="wim:F:/sources/install.wim#Windows 7 PROFESSIONAL"
xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>

[/sourcecode] Note that you will need to edit this content for your own circumstance:
In line 5, the processorArchitecture must be set to “amd64” for Windows 64bit, or “x86” for Windows 32bit.
In lines 12 and 13 the paths to the ProfilesDirectory and the ProgramData location.
In line 7 the Windows edition must be set: PROFESSIONAL, HOMEBASIC, HOMEPREMIUM, ULTIMATE or ENTERPRISE

Miscellaneous utilities

Towards the end of the installation it will be necessary to delete some folders, but there might be files opened from these folders, so you will need to kill the processes that opened the files. You can do this with the Microsoft Sysinternat Process Explorer command, which you can get from here. Copy the procexp.exe to the USB Flash drive.

Start

Boot from the Windows Installation DVD. The BIOS should be set to boot from the disk you will install Windows from but you will need to be able to intercept the boot sequence so it will boot from the DVD, on my computer I do this by pressing the F12 key during bootup but this will vary with different makes of motherboards.

Windows will load its set up file and let it continue until you are asked for the language, time zone etc. If you want to create a GPT partition then make sure that the drive you install it on has no other partition/volumes. If you want to create an MBR artition then make sure that the drive has a formatted partition. You can do this with the command link diskpart utility.

How to use diskpart to partition a disk and assign volume letters
Although at this point iot is not necessary to do anything other than get the disk that you are installing Windows to ready. There is no benefit to assigning other drive letters now, as they will undoubtedly need changing later as the installation progresses.
diskpart is a available from the Windows commandline which you can access during the Windows installation by pressing Shift-F10.
at the command prompt enter diskpart and a diskpart command prompt will display “>
Some of the most useful command are,

list disk displays the available disks
list partition displays the available partitions on the selected disk
list volume list all the volumes and assigned drive letters
select disk=x where x is the number of the disk as shown by list disk
select volume=x where x is the number of the volume shown by list volume
select partition=x where x is the number of the partition on the selected disk as shown by list partition
clean removes all partitions and volume formatting from the selected disk
create partition primary creates a primary partition on the selected disk using all the unallocated space
format fs=ntfs quick performs a quick format on the selected partition or volume
remove letter=x Remove the drive letter x assignment from the selected volume
assign letter=x assigns x as the drive letter for the selected volume
help to show more detailed help on these and other commands. Technet help
exit to exit the diskpart program

Warning – incorrect use of diskpart can cause loss of data and your computer may not boot.

After setting the language, keyboard and timezone Windows will install its software, including the Users, Program Files and Program Data to the C: drive,. It will pause when it reaches the point of wanting a new user created, and this is when we can start using the newly installed Microsoft System Preparation Tool, SysPrep.exe. Before creating the new user we can get into a minimal version of Windows called the AudiCode by pressing CTRl-Shift-F3 – the machine will reboot and will restart the new installed Windows into Audit Mode. When it restarts a SysPrep popup will be displayed, this can be dismissed. Open up a normal command prompt from the Start Menu.

At this point you should run diskpart, to create the needed partitions, format the volumes, assign drive letters. See the “How to use diskpart to partition a disk and assign volume letters” above. In particular you will need to assign letters and format the volumes that you will be using for the Users and Program Files, as well as setting the drive letter for the CD/DVD drive which will be the source location for the installation. You can also use the GUI Computer Management Console, (right button on My Computer then Manage and Disk Management) to assign the drive letters and format the drive.

After existing diskpart, copy the unattended.xml you created on your USB Flash drive in the preparation stage to the root directory of a drive that you will be putting your data or programs onto after making sure that the ProfilesDirectory and ProgramData elements in this file match with your drive assignments, for example I used the D: drive, and also that source location and description is correct, in my case: source=”wim:F:/sources/install.wim#Windows 7 PROFESSIONAL”

In the command window make C:\Windows\System32\SysPrep the current folder and enter the following command
sysprep.exe /audit /reboot /unattend:D:\unattended.xml ensuring that this is the location of the unattended.xml file.

SysPrep will start executing the instructions and the unattended.xml script and all being well will reboot the computer and again arrive back in Windows Audit Mode with the System Preparation Tool pop up window. Make sure that the System Clean Up Action Combobox is set to “Enter System Out-Of-Box Experience (OOBE), and the Shutdown option is set to reboot, and click OK.

Windows will reboot and no longer be in Audit Mode. At this point in my example the Windows folder will be installed on the C: as will the “Program Files” and “Program Files (x86)” folder(s) (the latter only for Windows 64-bit). Additionally on the C: drive will be a Users folder and the hidden “ProgramData” folder left over from the very original part of the installation. We will fix this part up soon.

Also there should be a hidden “ProgramData” folder on my D: drive and Users folder on my E: drive.

We need to now copy the “Program Files” and for Windows 64-bit the “Program Files (x64)”. Although you can use XCOPY for this, a better options is to use RoboCopy which ensure all the permissions, ACL, and ownership information is copied across.

the commands for this are:

robocopy "C:\Program Files" "D:\ProgramFiles" /E /COPYALL /XJ
robocopy "C:\Program Files (x86)" "D:\ProgramFiles (x86)" /E /COPYALL /XJ

You should not see any errors with this copy operation and the summary of the operation should show all source files were copied with none skipped

Next we will attempt to delete both these source folders with the Remove Directory command rmdir.
rmdir "C:\Program Files" /s /q
rmdir "C:\Program Files (x86)" /s /q
rmdir "C:\Users" /s /q
and then the hidden ProgramData with
rmdir "C:\ProgramData" /s /q

There is a high probability that this will not completely remove all files and you will see an “Access Denied” because files are in use, take a note of the files that could not be removed if any. It is curious that despire Windows having just installed the “ProgramData” folder onto a different drive that it still opens files from the C:\ProgramData folder. If you check the Windows environment variables with the set command, you will see that the ProgramData location is set to D:\ProgramData, but such is the affinity of Windows to use the C: drive for everything.

We will need to use brute force to stop the processes that are holding these files open, which comes to the Sysinternals Process Explorer, procexp.exe that we copied to the USB drive. Change to the USB flash drive, and enter the command in the command window:
procexp.exe
which will launch the Process Explorer window. From the “Find” mnu option select “Find Handle or DLL”. In the searchbook enter the name of oe of the .DLL files that could not be deleted from the Program Files or ProgramData folders. If there are multiple matches select the one that matches the folder that you could not delete, and close the search Window. The Process that opened that file will be highlighted in the Process Explorer window. Right click on that process and select “Kill”. This should release this file, as well as any others that it opened. Retry deleting the folders.

Repeat this step until there are no errors and the “C:\Program Files”, “C:\Program Files (x86)” if applicable, the previously hidden C:\ProgramData and C:\Users folders are completely gone from the C: drive. There shoudl be little left in the C: drive, except the C:\Windows C:\Perflogs folders.

Use the dir command to look for normal files folders, or the dir /ah to show hidden files and folders.

Windows has a strong affinity for the C: drive and although everything should use either the registry or the environmental variables, not everything will be so well behaved and many programs non-Microsoft and even Microsoft might hard code the location of these to the C: drive.

Rather than fight this we will used a Windows feature called folder redirection which has been around for many years but only started being used a lot from Windows Vista onwwards called junctions. Junctions are symbolic links which transparently redirect request to one folder to another.

To create these junctions use the follwing command:
mklink /j C:\Users E:\Users
mklink /j "C:\Program Files" "D:\Program Files"
mklink /j "C:\Program Files (x86)" "D:\Program Files (x86)"
mklink /j C:\ProgramData D:\ProgramData

Do a directory listing of the C:\ folder to verify that these folders exist, and also do dir "C:\Program Files" and for each other other folders to verify that they are pointing transparently to the files on the other drives.

At this point you shuld be able to close the command windows and then back at the Windows installation screen create a default user, and give the computer a name, and proceed with the installation.

Log into Windows and then verify that everything is in the right place, and as a last clean up option open explorer to the C: drive and set the properties of the ProgramData folder to hidden.

You should notice a marked difference in the speed that Windows loads and logs in.

At this stage I install Acronis TrueImage to backup the multiple disks to the G:\drive, and then proceeded to install the motherboard manufacturers drivers and utilities, and proceeded to the rest of the installation of software.

Part 2 of the blog discusses longer term experiences.