Tenant to Tenant Device Migration using ForensiT – User Profile Wizard

In a follow on to one of my last posts in which I mentioned I was living in a world of Tenant migrations, this remains true. I am migrating hundreds, if not thousands of devices from various Microsoft Tenants to other Microsoft Tenants, using a variety of methods/tools.

Devices being migrated include iOS, Android and Windows devices. This post will focus mainly on Windows Devices – Hybrid domain joined, and Azure joined scenarios, and the migration tool of choice, ForensiT Domain Migration — take note, this is all done using the Corporate Edition.

ForensiT User Profile Wizard is a cheap and cheerful utility that acts as a Swiss army knife when performing Tenant Migrations, at least on the Windows Device side of things. Some blurbage from the website;

Large-scale migration made easy

ForensiT (User Profile Wizard) has been used to automatically migrate millions of workstations to new domains. It can be used to migrate workstations to a new domain from any existing Windows network; it can join standalone computers to a domain for the first time, or migrate workstations from a domain back to a workgroup; it can also migrate user profiles to Azure AD user accounts.

No need to lose personal data and settings

A User Profile is where Windows stores your stuff. Normally, when you change your user account Windows will create a new profile for you, and you lose all your data and settings – your “Documents”, “Pictures” and “Music” files and all the other information that makes your computer personal to you, like your desktop wallpaper, Internet favourites and the lists of documents you’ve recently opened.

User Profile Wizard is an easy-to-use migration tool that means this doesn’t need to happen – you can simply migrate your original profile to your new user account. User Profile Wizard does not move, copy or delete any data. Instead it configures the profile “in place” so that it can be used by your new user account. This makes the process both very fast and very safe.


  • Migrates all user profile data and settings on Windows 10 and Windows 11
  • Automatically joins a machine to a new domain
  • Migrates profiles to Azure AD
  • Migrates profiles from Azure AD
  • Supports domain migrations over a VPN
  • Supports all Active Directory and Samba domains
  • Migrates from a domain back to a workgroup
  • Includes Enterprise strength scripting support
  • Supports push migrations of remote machines
  • Tried and trusted – over 2.5 million licenses sold

What it does?

As far as I can tell (and since confirmed by ForensiT Support), ForensiT User Profile Wizard, is fairly simple in operation… but… mostly due to language, can be quite tricky to tame. Based on what I have seen, ForensiT does little more than;

  • Re-map/repurpose the “current” User profile, with a future state profile.
    • Should the user login with old credentials, a NEW profile will be created, because due to the above, the old profile technically no longer exists/is no longer assigned to “the old credentials”.
  • ReACL the user profile, so that the future state profile (for example, Azure Object ID, has permission)
  • Performs a remove/drop/disconnect from Domain/Tenant
  • Deploys a Microsoft Windows Configuration Designer created Provisioning Package
  • Reboots the device (initiated by install-provisioningpackage packagename.ppkg -forceinstall)
  • Performs a re-registration of Windows AppX Programs/Applications (Uses upwpm2.exe)
    • Shows “Updating Apps” during first logon post migration.
    • Records a log file to %LocalAppData%\ForensiT\
    • Has caused a few headaches on Windows 10 devices such as Start Menu not working, or Search Bar not working etc…

Taming the “Beast”

I work with a lot of techies, and amongst them, User Profile Wizard is seen as some kind of dark art. The official ForensiT user guide is very good, but the language used within can often confuse, to the point whereby it’s taken a few attempts to get to a happy place. I don’t know it all, but I feel I know enough… so if anyone else reading this has any ForensiT pointers, I’m all ears!

With my latest migration task, I’ve ended up creating a wrapper to assist with the operation of User Profile Wizard, and, in relation to the configuration of the User Profile Wizard package creation, I’ve also created a few scripts to help there too…

Getting started

Before starting, there are a few prerequisites we need to adhere to before we even touch User Profile Wizard.

Creating the Migration Package

Launch the User Profile Wizard Deployment Kit.

Skip the welcome screen, and select whether you need/want to Create a new migration project, or Edit an existing migration project.

In step 3, you need to supply some information…

You need to supply the Domain Name (AD/AAD) and/or Workgroup name. You can see here, that “itonlinedomain.onmicrosoft.com” is supplied, and Azure AD ticked, to show that the target is an Azure AD tenant.

Because of this, we’re asked to supply the Azure ID file path. This is the XML file created as part of the prerequisite steps I listed out above. This file contains the AAD Object ID’s of the users from the target tenant.

And, because we’ve ticked the Azure AD box and want the Migration to actually perform the Azure AD domain join, amongst other things, we must supply the location to the Provisioning Package we created as part of the prerequisite steps.

Clicking next takes us on to Step 6, which questions us about our “as-is” environment.

If the current environment is neither an AD or AAD infrastructure, click No and next… but in our instance here, we have a Hybrid scenario. So we’ve ticked Yes to it being (A)AD. We’ve supplied the NETBIOS name of the existing domain (INTERNAL\jvincent), which is used to perform the User account lookup, and we’ve referenced the fact that this is also an Azure AD tenant.

Failure to supply the NETBIOS name and lookup file, can result in errors/problems when migrating.

From experience, if the Existing Configuration is AAD ONLY, then you can tick Yes, leave the Existing Domain Name as “azuread” and tick the Existing Azure AD tenant.

Clicking next, we’re moved to Step 8 in which we’re asked to supply the User Lookup file we generated as part of the prerequisite stages. A little note on this. The lookup file needs to exist out of the ForensiT User Profile Wizard folder, and during the finalisation of the migration package, this will be copied INTO the folder.

Clicking next, we’re asked if we want to supply a Local Admin account for the package to run as. In my experience and example, Local Admin accounts are few and far between, so this has always been left blank.

Clicking next, takes us on to the final input screen. Step 11. In which we’re asked about how we wish to run the package.

Ticking use script, allows us to select one of four preconfigured scripts supplied by ForensiT. The options are;

  • Migrate-All.ps1
  • Migrate-BySID.ps1
  • Migrate-LastLoggedOnUser.ps1
  • Migrate-LastLoggedOnUserPrompt.ps1

Reading the scripts/manual will provide more details as to the functions of each, but so far, I’ve only used Migrate-LastLoggedOnUserPrompt.ps1. Which when running the Migration, you are prompted to supply the target state UPN of the user that you wish to become the “profile owner”. Whilst Migrate-LastLoggedOnUser.ps1 (Same script, but without a prompt) could be used, the prompt is being used as a kind of failsafe pre-migration check, as it is reliant on user input.

Ticking “Deploy using a Desktop Management tool” option, strips the absolute paths from all the supporting XML, PPKG and PS1 files, and encapsulates everything into a single .exe file, which means, if you were to prepare the file to run without user interaction, you could theoretically deploy this en-masse, to run silently and without any user input. This would be a good candidate for running out of hours etc…

And finally, “Create Log File“. Who doesn’t want a log file! My only niggle with this, is that it’s not very verbose!

And that concludes the package creation really… you’ll have noticed that the UI skips certain steps based on answers.. I have never seen any of the other steps, so my assumption is that they’re very “on-premises”/Workgroup specific settings being skipped… so if you’re coming from a true legacy environment, this might be something to consider. It’s worth adding at this point that the ForensiT team operate a Support Forum, and whilst it’s not hugely active, there’s a lot of good information on there should you have questions/need to validate something!

A tip!

If you intend to use a Deployment file, then, before you click the “Create Single Deployment File” button on the final step (Step 13). Click “Open Deployment folder“. In here you will find a file called “profwiz.config“. Open this file in your favourite text editor, and here you will see the parameters that will be baked in to your deployment file.

Under “Corporate Edition” settings, I like to turn Silent mode off, and ensure Remove Admins is set to true.

    <!-- Corporate Edition Settings -->

After making any changes to your profwiz.config file, save it, and then click the Create Single Deployment File button. Doing so, will generate the all encapsulating Migrate-*.exe file, that you can distribute.

So what next?

After you’ve run through the User Migration Wizard, you’re going to end up with a folder structure not too dissimilar to this;

If you opted to tick the Deploy using a Desktop Management tool option during creation, you’ll notice there is an executable in your package directory. This .exe contains all the supporting information, and can be distributed via a management tool, or even simply copied via USB/whatever means necessary to a device, to be executed (elevated!)

The latter is what I’ve been doing, in a bid to retain a little more control over proceedings. So we drop the .exe on to a device, and then execute it with Admin privileges. Due to the use of Migrate-LastLoggedOnUserPrompt.ps1, we’re then prompted for the Target UPN of the designated user.

User Profile Wizard performs a lookup in the supplied .CSV, and if the User/UPN is found, the migration continues.

A close up of the log file/on screen output (which is displayed when turning Silent OFF in profwiz.config).

ForensiT User Profile Wizard 24.5.1290
Licensed to  License No. 
Copyright (c) 2002-2023 ForensiT Software Ltd
12/01/2024 14:01:44.689 Creating migration service... Done.
12/01/2024 14:01:44.757 Starting migration service... Done.
12/01/2024 14:01:45.845 Target device: VINI-VM-01
12/01/2024 14:01:45.851 OS build 10.0.19045.3803. Version 22H2.
12/01/2024 14:01:45.853 Domain: internal
12/01/2024 14:01:46.300 Migrating user account "jvincent"
12/01/2024 14:01:46.342 Processing UWP Apps... Done.
12/01/2024 14:01:47.603 Setting Registry ACLs... Done.
12/01/2024 14:01:56.045 Set Registry ACLs in 8.438 seconds.
12/01/2024 14:01:56.048 Closing Apps... Done.
12/01/2024 14:01:56.213 Setting Profile ACL... Done.
12/01/2024 14:03:12.215 Set Profile ACL in 75.997 seconds.
12/01/2024 14:03:12.217 Creating Profile registry keys... Done.
12/01/2024 14:03:12.562 Adding new account to local groups... Done.
12/01/2024 14:03:12.624 Setting james.vincent@itonlinedomain.onmicrosoft.com as default logon... Done.
12/01/2024 14:03:18.345 Calling Provisioning Package... Done.
12/01/2024 14:03:32.159 Migration Complete!

You can see the last steps here, are to call the provisioning package, which User Profile Wizard achieves by running install-provisioningpackage packagename.ppkg -forceinstall. What then occurs is that the installation of the Provisioning Package forces a reboot, so shortly after this, you will see the device reboot.

After which, depending on your device state/Provisioning Package configuration, you’ll be thrown to a Logon Screen that isn’t yet connected to any form of domain. Just sit on your hands for 5 minutes here, because in the background the provisioning package is doing its thing.

After returning from making a cup of tea, you should find you’re now prompted to provide domain credentials, be it on-premises AD details, or your AAD Email Address.

A tip!

Change the Lock screen wallpaper in your PPKG. That way, you can see visually, when the provisioning is complete.

During the first logon post migration, you should see “Updating Apps… XX%” What this is doing, is reregistering all the default Microsoft AppX files, to your user profile.

This is triggered by UPWPM2.exe which is supplied with User Profile Wizard. This process writes out to %LocalAppData%\ForensiT\Migrate-AppxPackage.log and on a few occasions I’ve had oddities/errors post migration. Resulting in broken Start Menu’s, broken Search Bars and other broken AppX files, see the Tip below.

And once the Apps have updated, you should be at the User’s “normal” desktop, but logged in using their new credentials. And that is effectively it…!

A tip! (If things don’t work fully after Migration…)

Above I mentioned that on occasion, I would see oddities with AppX programs not functioning post migration. This seems to be due to re-registration failures when UPWPM2.exe runs at that first logon. The consensus is Security Applications are interfering with the process, but this is very environment specific. A log from a device with issues, looks like this;

16/01/2024 16:48:32 upwpm2 called with no parameters.
16/01/2024 16:48:32 Clearing C:\Users\jvincent\AppData\Local\Microsoft\Windows\WebCache
16/01/2024 16:48:32 Clearing C:\Users\jvincent\AppData\Local\Packages\Microsoft.Windows.Search_cw5n1h2txyewy
16/01/2024 16:48:32 DEBUG: C:\Users\jvincent\AppData\Local\Packages\Microsoft.Windows.Cortana_cw5n1h2txyewy not found
16/01/2024 16:48:35 Package registration complete: Microsoft.VCLibs.140.00
16/01/2024 16:48:35 Package registration complete: Microsoft.NET.Native.Framework.2.2
16/01/2024 16:48:42 Package registration complete: MicrosoftWindows.UndockedDevKit
16/01/2024 16:48:46 Package registration fails: Microsoft.Windows.StartMenuExperienceHost
16/01/2024 16:48:46 Error 0x80070005: Windows failed to create AppContainer profile for package Microsoft.Windows.StartMenuExperienceHost_10.0.19041.1023_neutral_neutral_cw5n1h2txyewy.
16/01/2024 16:48:46 Package registration complete: Microsoft.Windows.ShellExperienceHost
16/01/2024 16:48:50 Package registration fails: Microsoft.Windows.Search
16/01/2024 16:48:50 Error 0x80070005: Windows failed to create AppContainer profile for package Microsoft.Windows.Search_1.14.9.19041_neutral_neutral_cw5n1h2txyewy.
16/01/2024 16:48:50 Package registration complete: Microsoft.Windows.ContentDeliveryManager
16/01/2024 16:48:50 Package registration complete: MicrosoftWindows.Client.CBS
16/01/2024 16:48:51 Package registration complete: Windows.CBSPreview
16/01/2024 16:48:55 Package registration complete: Microsoft.MicrosoftEdge.Stable
16/01/2024 16:48:55 MS Private Key not found.
16/01/2024 16:48:55 Updates complete.

With thanks to the ForensiT support team. If you find any AppX related issues, such as the Start Button/Search bar not working, then the recommendation is to run UPWPM2.exe again, manually. I wrote a little helper to do this for me, as it requires running the file as the actual User, and with elevated permissions (in almost all cases, users should not have admin rights!)

# Run this script/these commands, AS THE USER, in ELEVATED context
# You may need to add the user to the Local Administrators group manually first
# net localgroup administrators "azuread\full.upn@domain.com" /add
# or 
# net localgroup administrators "NETBIOS\username" /add
# Then run an elevated PowerShell as the User and perform the following actions.
taskkill /F /IM explorer.exe
taskkill /F /IM ShellExperienceHost.exe
taskkill /F /IM StartMenuExperiencehost.exe
taskkill /F /IM SearchUI.exe
taskkill /F /IM RunTimeBroker.exe
Start-Sleep 3
Get-AppxPackage Microsoft.Windows.ShellExperienceHost | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"}
upwpm2 -Force
Get-Process "upwpm2" | sort StartTime -Descending | select -first 1 | Wait-Process
$myuser = whoami
net localgroup administrators "$myuser" /delete

What this is effectively doing is adding the Local User to the Local Administrators group. Killing a few tasks. Requesting the Local User credentials. Running a few commands as the user, in Elevated mode. Waiting for 2 minutes to allow the scripts to run. Then tidying up after itself.

If the above doesn’t work for you, then perform the steps manually.

And if all else fails, reach out to ForensiT for assistance! The team there have been nothing but helpful! Don’t overlook the YouTube Channel or Support Forum either!

James avatar

Leave a Reply

Your email address will not be published. Required fields are marked *