Skip to content

Profile migration

Totl.Migrate moves a user's Windows profile onto a new account — the native replacement for paid Profwiz. It is high risk and gated for safety: it runs only via -Phase migrate, defaults to a dry run, and the native SID-reassign path refuses to run on physical hardware until you've validated it on a VM.

Modes

  • copyData (free default): robocopy the profile data (Desktop/Documents/browser profiles/etc.) into a fresh profile, then enable OneDrive Known Folder Move. No SID work; reliable file movement.
  • sidReassign (native, VM-gated): reassign the existing profile to a new local or on-prem domain account — ProfileList rewrite → icacls /substitute old SID → new SID → NTUSER.DAT hive ACL. This is the real fix for the permission errors plain robocopy leaves behind.

For Entra (Azure AD) in-place migrations, ForensiT Profwiz / USMT remain the documented fallback (Invoke-TotlProfileWizard), because a scripted Entra reassignment isn't reliable outside OOBE.

Safety gates

  • migrate.dryRun (default true) — logs the exact plan (each step) and changes nothing. Set to false only after reviewing the plan.
  • migrate.requireVM (default true) — sidReassign refuses on physical hardware. Test on a VM first; set false to allow on real machines once validated.
  • Live apply of the SID-reassign steps is deliberately withheld in code pending VM test-harness sign-off; the pure plan and argument builders (New-TotlMigrationPlan, Get-TotlIcaclsSubstituteArgs, Get-TotlRobocopyArgs) are unit-tested and are what the apply step will consume.

Running it

# Review the plan (dry run) for a config that has migrate.enabled = true
powershell -ExecutionPolicy Bypass -File .\src\Invoke-Provision.ps1 -ConfigPath .\config\clients\contoso.config.json -Phase migrate

Set migrate.sourceAccount (the old profile's account) and migrate.targetAccount (the new owner) in the client config, pick the mode, and keep dryRun: true until you've read the logged plan.