Premise

If you use Windows long enough, eventually you will run into a broken user profile. Sometimes its the start menu that busted, or the Windows store wont open etc. If the typical recommendations of sfc / dism / re-register appx packages with PowerShell fails to remedy the issue, see if the issue is isolated to the user profile. Log into another Windows user account and see if the issue persists. If the issue is not present in another Windows account, then you have a case of a borked Windows user profile.

You can try to keep fixing the issue, but Ive found its typically faster and easier to just backup and “blow-out” the user profile

Backing up user data and removing the profile.

  1. Create a backup folder to store files. C:\backup for example.

  2. Export browser data, including saved passwords, bookmarks etc. If you store passwords in Chrome/Firefox/Edge and you are not syncing an account, the passwords will be lost unless they are exported.

  3. Make note of any obvious user customizations, such as taskbar layout, outlook layout, background pictures etc.

  4. Make note of any user installed software. This can be done by checking the Uninstall registry key under HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall

  5. Sign out and sign into a local admin account

  6. Remove the affected user profile registry key under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\ The keyname will be the SID of the user account.

  7. Reboot

  8. After reboot, log back into the local admin account. Rename the user folder adding .bak to the name.

    Some of this process can be easily automated. The following script will export a list of user specific programs, also backup and remove the user profile registry key.

#Requires -RunAsAdministrator
$userprofiles = (Get-ChildItem registry::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\" | get-itemproperty).pschildname
$users = foreach ($user in ($userprofiles | where { $_.Length -gt 20 }))
{
	$sid = $user
	try
	{
		[pscustomobject]@{
			'UserName' = ([System.Security.Principal.SecurityIdentifier]($sid)).translate([System.Security.Principal.NTAccount]).value
			'SID'	   = $sid
			'ProfilePath' = (Get-ItemProperty registry::HKEY_LOCAL_MACHINE\"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid").ProfileImagePath
		}
	}
	Catch {}
	
}

function Welcome
{
	
	Write-Host "####################################################################################################"
	Write-Host "User Profile Backup/Removal Tool Version 1.0`nAuthor: David Just" -ForegroundColor DarkCyan -BackgroundColor Black
	Write-Host "Welcome to the User Profile Backup/Removal Tool" -ForegroundColor Green -BackgroundColor Black
	Write-Host "#################################################################################################### `r`n"
	Write-Warning "This tool performs potentially descructive actions. `nBefore running, please export and save browser passwords, bookmarks etc."
	pause
	Write-Host "[1] Backup/remove user profile registry key and reboot`n[2] Rename user profile folder"
	$global:option = [int](Read-Host "Which step would you like to perform?")
}

function ListUserProgram
{
	param (
		$SID,
		$ProfilePath 
	)
	reg load HKU\brokenuser $ProfilePath\NTUSER.DAT
	$RegPath = "registry::HKU\brokenuser\Software\Microsoft\Windows\CurrentVersion\Uninstall"
	try
	{
		$softwareTable = Get-Childitem $RegPath -ErrorAction Stop | Get-ItemProperty | where displayname | select displayname, displayversion 
		New-Item -ItemType directory -Path $env:SystemDrive\backup -force | Out-Null
		$softwareTable | Export-Csv "$env:SystemDrive\backup\usersoftware.csv" -NoTypeInformation
	}
	Catch
	{
		$_
		"Error exporting user software list"
		"Stopping Operation"
		reg unload HKU\brokenuser 
		sleep 5
		exit 1
	}
	
	
}

Welcome

function RemoveAndBackupUserProfile {
	[Cmdletbinding(SupportsShouldProcess)]
	param (
		[string]$SID,
		[string]$profilepath
	)
	reg export "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid" $env:SystemDrive\backup\profile.reg
	
	$profilepath | Out-File $env:SystemDrive\backup\profilepath.txt
	
	Remove-Item registry::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$sid" -Recurse
	CheckandSuspendBitlocker	
	"Profile removed from registry. Rebooting in 5 seconds"
	shutdown /r /t 5
	
}

function CheckandSuspendBitlocker # Suspend Bitlocker protection for reboot
{
	$Status = (Get-BitLockerVolume -MountPoint $env:systemdrive).protectionstatus
	if ($Status -eq "On")
	{
		"Suspending bitlocker protection..."
		Suspend-BitLocker -MountPoint $env:SystemDrive -RebootCount 1
	}
}

switch ($option)
{
	1 {
		$index = 1
		foreach ($user in $users)
		{
			"[$index] {0}" -f $user.username
			$index++
		}
		$Selection = [int](Read-Host "Which user account do you wish to backup and remove?") - 1		
		
		Write-Host "Exporting User Program List..."
		sleep 1
		ListUserProgram -SID ($users[$Selection]).SID -ProfilePath ($users[$Selection]).ProfilePath
		
		"Program list saved to $env:SystemDrive\backup\usersoftware.csv"
		Pause
		RemoveAndBackupUserProfile -SID ($users[$Selection]).SID -profilepath ($users[$Selection]).ProfilePath -Confirm
	}
	2 {
		$profilepath = Get-Content $env:SystemDrive\backup\profilepath.txt
		Rename-Item $profilepath -NewName ($profilepath + ".bak")
		"Renamed {0} to {1}" -f $profilepath,($profilepath + ".bak")
		sleep 5
	}
}
  1. Logout. Log back in as the original user
  2. All user data still remains in the original renamed user folder (including registry information). If needed, move any data needed back from the backup folder.
  3. Reinstall any user specific programs. If you run the script, these will be listed out in the CSV file under C:\backup.

And thats it! Sometimes its just better to cut your losses and start fresh.