How to Migrate Local User Profiles to Domain Accounts While Preserving Settings in Windows Vista x64 Development Environments


2 views


When transitioning standalone Windows Vista x64 development workstations to an Active Directory domain, we face the critical challenge of preserving existing local user profiles. Developers typically accumulate:

  • Custom environment variables and PATH configurations
  • IDE settings (Visual Studio, Eclipse, etc.)
  • Source code repositories and project files
  • SSH keys and credential managers
  • Shell customizations (command prompt/PowerShell profiles)

The Windows User State Migration Tool (USMT) provides the most robust solution, though we'll also cover manual alternatives for specific scenarios.

First, download USMT from Microsoft's website. Here's the basic workflow:


# Sample USMT command sequence
scanstate.exe \\server\migrationstore /i:migapp.xml /i:miguser.xml 
/offlineWinOld:C:\Windows.old\Windows /o /c /v:13 /l:scan.log

# After domain join
loadstate.exe \\server\migrationstore /i:migapp.xml /i:miguser.xml 
/lac /lae /c /v:13 /l:load.log

Key parameters for developers:

  • /lac: Creates local accounts if domain join fails
  • /lae: Enables created accounts
  • Custom XML files to include development-specific paths

For situations requiring more control:


# Export registry keys
reg export HKCU\Software\Microsoft\VisualStudio \\backup\vs_settings.reg
reg export HKCU\Environment \\backup\env_vars.reg

# Copy profile data (run as admin)
robocopy C:\Users\olduser C:\Users\newuser /E /COPYALL /XJ /R:0 /W:0 /ZB /MT:32

Pay particular attention to:

  1. Version control configurations (.gitconfig, .hgrc)
  2. SSH known_hosts and config files
  3. Database connection profiles
  4. Custom certificate stores

After migration, verify:


# Check environment variables
Get-ChildItem Env: | Where-Object { $_.Name -like "*DEV*" }

# Test path resolution
gcm msbuild,cl,csc | Format-Table Path

# Validate source control
git --version
hg --version


When joining Windows Vista x64 workstations to an Active Directory domain, developers often face a critical dilemma: how to maintain their carefully configured local profiles containing:

  • Source code repositories (often approaching 1GB in size)
  • IDE customizations (Visual Studio, Eclipse, etc.)
  • Environment variables and PATH configurations
  • SSH keys and development credentials
  • Custom registry tweaks for development tools

The key is to use Windows' built-in profile migration tools before domain join. Here's the technical workflow:

# PowerShell script to check current profile size
$profilePath = [Environment]::GetFolderPath('UserProfile')
$profileSize = (Get-ChildItem $profilePath -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Host "Current profile size: $([math]::Round($profileSize,2)) MB"

1. Pre-Join Preparation:

# Create migration store
mkdir C:\ProfileBackup
xcopy "%USERPROFILE%\*" "C:\ProfileBackup\" /E /H /K /X /Y

2. Domain Join Execution:

# Command to join domain (run as admin)
netdom join %COMPUTERNAME% /domain:YOURDOMAIN /userd:DOMAIN\adminuser /passwordd:*

3. Post-Join Profile Restoration:

# Registry modification to enable profile copy
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /v "ProfilesDirectory" /t REG_EXPAND_SZ /d "%SystemDrive%\Users" /f

# File copy operation with proper permissions
robocopy C:\ProfileBackup "%USERPROFILE%" /E /COPYALL /R:1 /W:1 /LOG:C:\Migration.log

For development-specific items that often break during migration:

# Fixing common VS Code issues
$vscodePath = "$env:APPDATA\Code\User"
if (Test-Path $vscodePath) {
    icacls $vscodePath /grant "%USERDOMAIN%\%USERNAME%":(OI)(CI)F /T
}

Here's a complete script I've used successfully in enterprise environments:

# DomainJoinWithProfilePreservation.ps1
param(
    [string]$Domain,
    [string]$AdminUser,
    [string]$AdminPassword
)

# Backup phase
$backupDir = "C:\ProfileBackup_$(Get-Date -Format 'yyyyMMdd')"
Write-Host "Backing up profile to $backupDir"
Copy-Item -Path $env:USERPROFILE -Destination $backupDir -Recurse -Force

# Domain join
Write-Host "Joining domain $Domain"
$securePass = ConvertTo-SecureString $AdminPassword -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($AdminUser, $securePass)
Add-Computer -DomainName $Domain -Credential $cred -Restart -Force

# Note: Script continues after reboot using Task Scheduler
# with trigger on user login to restore profile

After migration, verify these critical development components:

# Check Git configuration preservation
git config --global --list

# Verify environment variables
Get-ChildItem Env: | Where-Object { $_.Name -like "*DEV*" -or $_.Name -like "*PATH*" }

# Test IDE settings
if (Test-Path "$env:LOCALAPPDATA\JetBrains") {
    Write-Host "JetBrains IDE settings detected"
}