Wednesday, March 7, 2012

Moving the Profile folder to a different location under Windows 7 [UPDATE: Now for Windows 10! ]

UPDATE: 2019-12-24: Verified to work for Windows 10 Pro.
UPDATE: 2019-12-24: Added information on image indexes, and troubleshooting guide.
UPDATE: 2019-12-24: Add direct link to pre-built Unattend.xml.

There are many reasons why one may want to move C:\Users and C:\ProgramData to a new location, preferably on a different disk, the most important being separation of OS data from user-specific data.

The most common methods proposed all over the web are:
  • Messing with Registry settings (e.g., changing keys under HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CurrentVersion\ProfileList)
  • Using robocopy to copy everything over, then make an NTFS junction pointing to the new location (e.g. mklink /j C:\Users D:\Users)
  • using an answer file (unattend.xml) when installing Windows, to change the FolderLocations setting, see http://technet.microsoft.com/en-us/library/cc749305(v=ws.10).aspx
Method 3 seems to be the best-supported, given there's a nice article in Microsoft's KB (http://support.microsoft.com/kb/949977) about it, and that Setup creates the elaborate set of Junctions needed for backwards compatibility in the new location automatically.

Still, after numerous tries, Setup seemed to ignore the answer file I was providing in the root of a connected USB stick. It doesn't matter Microsoft's documentation says otherwise: http://technet.microsoft.com/en-us/library/cc749415(v=ws.10).aspx, no matter what I tried Setup ignored my unattend.xml.

The only way I could make it work was by placing it in the root of the newly installed %SYSTEMDRIVE%, i.e., C:, so here are detailed steps on how to do that:

  1. Download the Windows Automated Installation Kit (WAIK), and install it on a second computer. Or just download a pre-built Unattend.xml and jump directly to step 3
  2. Create an answer file using the Windows System Image Manager containing the necessary entries for the FolderLocations setting, in the oobeSystem phase (both for x86 and amd64 architectures)
  3. Create a bootable USB drive for installing Windows 7
    1. Use DISKPART to completely clear it, create a primary partition, format it as NTFS and mark it as active
    2. Copy the full contents of the Windows 7 installation DVD in the newly-created NTFS
    3. I also had to run BOOTSECT /nt60 J: at this point, although I'm not sure it's necessary
  4. Modify sources\install.wim on the USB stick so that it contains your unattend.xml file as well
    1. [UPDATED] Based on the version of Windows you wish to install, note its index in the install image:
      DISM /Get-ImageInfo /ImageFile:J:\sources\install.wim
    2. Mount the image on a local directory, but replace its index at the /index argument, based on the version you want to install, see step (1) above:
    3. DISM /Mount-Wim /WimFile:J:\sources\install.wim /index:1 /Mountdir:C:\wim 
    4. COPY unattend.xml C:\wim
    5. Unmount the directory
      DISM /Unmount-Wim /MountDir:C:\wim /commit 
If all goes well, you should be able to install Windows 7 from the USB stick ([UPDATED] remember to create a and format a second NTFS partition during Setup!) and see the fruits of your labor:
C:\>echo %userprofile%
D:\Users\vangelis


The setup logs under C:\Windows\Panther\UnattendGC\setupact.txt will confirm your victory:


oobeldr.exe] Status for unattend pass [oobeSystem] = 0x0
[oobeldr.exe] UnattendSearchExplicitPath: Found unattend file at [C:\unattend.xml]; examining for applicability.
[oobeldr.exe] UnattendSearchExplicitPath: Found usable unattend file for pass [oobeSystem] at [C:\unattend.xml].

...
[Shell Unattend] Running 'oobeSystem' pass
[Shell Unattend] FolderLocations: Moved 'C:\Users' to 'D:\Users'
[Shell Unattend] FolderLocations: 'ProfilesDirectory' set to 'D:\Users'
[Shell Unattend] FolderLocations: 'Public' set to 'D:\Users\Public'
[Shell Unattend] FolderLocations: 'Default' set to 'D:\Users\Default'
[Shell Unattend] FolderLocations: 'ProfileImagePath' set to 'D:\Users\Administrator'
[Shell Unattend] FolderLocations: Moved 'C:\ProgramData' to 'D:\ProgramData'
[Shell Unattend] FolderLocations: 'ProgramData' set to 'D:\ProgramData'



Enjoy your user data on a separate partition from the rest of the OS.

I can't get it to work!

The latest version of Windows I have verified this procedure with is Windows 10 1903.
If something breaks, please check the following:
  • Are you sure you have updated the right image in install.wim? Double check that the index you specified at the DISM command line corresponds exactly to the version you are deploying.
  • Are you sure a D: drive exists during installation? Press Shift-F10 during setup and use DIR to explore all drives.
  • It could be that your USB stick itself appears as D: instead of your second partition, which may be at E:. If this is the case, you need to remove your installation medium at the first reboot, right after Setup has completed the initial copy of all files, before it reboots into your hard disk.

1 comment:

  1. A short comment about your "BOOTSECT /NT60 J:" item above:

    The BOOTSECT.EXE program is found on your Window 7 Installation DVD, in the X:\BOOT folder (substitute X: for the actual letter of your DVD drive.)

    I had to run that BOOTSECT.EXE program immediately after using DISKPART to clean and re-format my USB drive. *Then* copy the Windows 7 DVD onto the USB drive. For some reason, it just wouldn't boot unless I did it in that order.

    But other than that minor little difference, I followed your instructions to the letter, and it all worked wonderfully -- thanks so much for posting this!

    ReplyDelete