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:
- Version control configurations (.gitconfig, .hgrc)
- SSH known_hosts and config files
- Database connection profiles
- 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"
}