Powershell: Migrate user to new environment

Hey You

It’s a nice snowy friday in April (wth?) and I wanted to share something with you.

At a client for whom I work now we had a little challenge that I knew Powershell would come to my aid as it always does. Let me explain the situation first.

The scenario for which I used Powershell.
Here’s the scenario


All 800+ users are working on a VDI which has an outdated Windows 10 en Microsoft Office which isn’t supported anymore by Microsoft. Because of some issues we have we need to upgrade/update literally EVERYTHING. But unfortunately it’s not that easy though

Challenge 1: VDI specs was too low.

The VDI specs that was given to the users wasn’t what Microsoft suggests. These are the specs:

  1. 2 vCPU
  2. 8 GB RAM
  3. 60 GB Hard Drive

This needs to be updated.

Challenge 2: AppData redirection

The AppData folder is redirected to the network drive. Normally this wouldn’t be an issue but in this case it is. Every user has a dedicated VDI so redirecting the AppData has no use so turning it off would help a lot.

Because the Windows is outdated, the AppData folder would probably (and it did) corrupt the new environment. So that needs to be fixed.

Challenge 3: GPO needs to be renewed

As you’ve guessed it; GPO still applies to the old settings of Windows and is not valid anymore. So a new OU needs to be created where the migrated users can be in and get the new GPO settings while the users that not have been migrated still can work with their VDI (does this make sense?).

Here comes the solution
Here comes the solution


These 3 challenges should not be a big thing. These can be done but imagine having 800+ users and not having an automated system. A lot… of… work.

An In-Place Upgrade (IPU) is out of the question because the hardware is going to be replaced. All VDI’s are instant clones so we had no choice but to hand over new VDI’s. This article will not cover the IPU or replacement of the VDI’s.

The following needs to be done. For convenience I will be referring to User A as the user that is going to get migrated.

  1. User A is member of an AD Group so that she (yeah it’s a she) can access her VDI. The user should be removed as a member from this AD group.
  2. User A needs to be moved to the new OU.
  3. User A has a profile path which points to the wrong directory and needs to be changed.
  4. AppData, NTUser.Dat and NTUser.ini file and folders has to be deleted.
  5. Files and folders from the old profile should be copied to the new profile folder.
  6. User A needs to be added to the AD Group so that she (it’s still a she) can access her new VDI.

Let’s start


Before we start; I am no Powershell Guru. I didn’t had a Powershell course nor do I claim that I am someone who is very very awesome in Powershell (I should though…). Not so long ago we had a podcast/webshow with Jeffrey Wouters where we discussed the posibilities and the great joy of Powershell, Devops and more. Check it out.

This is the way that I did it and there are probably a million ways to do it better. So if you are a Powershell Guru… here’s a laugh (but don’t laugh too hard)

#Well... I need to get the users from somewhere don't I?
#I can't get them from the AD because we are doing it in batches.
$Users = Get-Content -Path C:\Temp\usersMigrate.txt

#Some variables that show the old AD group, new AD group and the new OU
$oldADGroup = "old_ad_group"
$newADGroup = "new_ad_group"

#Here's where the magic starts
Foreach ($User in $Users) {

    Write-Host "Migrating $User"

    #Some more variables about the current profile path and the old profilepath
    $profilePath = "\\PRO\$User\Profile2022"
    $newProfilePath = "\\PRO\usdata$\$User\Profile2022.V6"
    $oldProfilePath = "\\PRO\usdata$\$User\Profile2019.V6\*"

    #Some other junk that was left in the old profile path that needed to be deleted
    $oldAppData = "\\PRO\usdata$\$User\Profile2019.V6\AppData"
    $oldEdgeBackup = "\\PRO\usdata$\$User\Profile2019.V6\MicrosoftEdgeBackups"
    $oldNTUserDAT = "\\PRO\usdata$\$User\Profile2019.V6\NTUSER.DAT"
    $oldNTUserINI = "\\PRO\usdata$\$User\Profile2019.V6\ntuser.ini"
    #Step 1; remove user as a member from the old AD group
    Get-ADGroup -Identity $oldADGroup | Remove-ADGroupMember -Members "$User" -Confirm:$false

    #Step 2; Move user to the new OU
    Get-ADUser -Identity $User | Move-ADObject -TargetPath $OU

    #Step 3; change the profile path within AD
    Set-ADuser $User -ProfilePath $profilePath

    #Step 4; remove all the junk
    Remove-Item -Path $oldAppData -Recurse -Force -Confirm:$false
    Remove-Item -Path $oldEdgeBackup -Recurse -Force -Confirm:$false
    Remove-Item -Path $oldNTUserDAT -Recurse -Force -Confirm:$false
    Remove-Item -Path $oldNTUserINI -Recurse -Force -Confirm:$false

    #Step 5; Create a new directory for the profile
    New-Item -ItemType "directory" -Path "$newProfilePath"
    #Step 6; Copy old data to new data (I just thought that maybe it would be easier to rename the old folder... whatevs)
    Copy-Item -Path $oldProfilePath -Destination $newProfilePath -Recurse -Force -Confirm:$false

    #Step 7; add user as a member to the new AD Group
    Get-ADGroup -Identity $newADGroup | Add-ADGroupMember -Members "$User" -Confirm:$false