Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The sample script provided in this article can help clean up orphaned profile information from the registry and the C:\users folder.
If profiles are incompletely or improperly removed, additional user folders can be created, or users may receive TEMP profiles upon logging in. In some cases, there can be many profiles in a state where TEMP profiles are used, even though these profiles haven't been logged into yet.
Applies to: Windows 10, Windows 11, Windows Server 2016, and later versions
Important
This sample script is not supported under any Microsoft standard support program or service.
The sample script is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose.
The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.
#
# usage:
# PowerShell /file OrhanedProfile.ps1 [-clean]
#
# The clean switch enables the deletion to take place. Otherwise, it reports what it could do.
#
Param(
[switch]$bClean = $false
)
# Check if running as an Administrator
if( -NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") )
{
Write-Host "Please run as a member of the Administrators group"
break
}
# Get Profiles folder
$ProfilesListRegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
$ProfilesFolder = $null
$ProfilesFolder = Get-ItemPropertyValue -Path $ProfilesListRegPath -Name "ProfilesDirectory"
If( $ProfilesFolder -eq $null )
{
Write-Host "Error getting the base profile folder."
break
}
"Profile folder: $ProfilesFolder"
#######################################
# Begin to get and check ProfileList key information
"Collecting ProfileList key information..."
"=" * 40
$WellKnownProfiles = @("S-1-5-18","S-1-5-19","S-1-5-20")
$ProfileListCount = 0
$ProfileListWarnCount = 0
$ProfileListInfo = @{}
Get-ChildItem -Path $ProfilesListRegPath -Exclude $WellKnownProfiles | ForEach-Object `
{
$ProfileSID = $_.PSChildName
$ProfilePath = $null
$ProfilePath = Get-ItemPropertyValue -Path $_.PSPath -Name "ProfileImagePath"
if( $ProfilePath -eq $null )
{
"Unable to read ProfileImagePath from ProfileList entry: $($_.Name)"
}
else
{
$ProfileListCount++
if( $ProfileSID -like "*.bak" )
{
"WARNING: .BAK ProfileList entry exists: $ProfileSID"
$ProfileListWarnCount++
}
try{
$ProfileListInfo.Add( $ProfilePath, $ProfileSID)
}
catch
{
$ProfileListInfo[ $ProfilePath ] = $ProfileListInfo[ $ProfilePath ] + ";$ProfileSID"
"WARNING: Multiple profile entries reference '$ProfilePath': $($ProfileListInfo[$ProfilePath])"
$ProfileListWarnCount++
}
}
}
"ProfileList Count...: $ProfileListCount"
"ProfileList Warnings: $ProfileListWarnCount"
#######################################
# Check for Orphaned ProfileListEntries - entries that reference deleted profile folders
""
"Looking for orphaned ProfileListEntries"
"=" * 40
$OrphanedProfileEntries = 0
$ProfileListInfo.GetEnumerator() | ForEach-Object `
{
$bOrphaned = $false
if( -not (Test-Path -Path $_.Key ) )
{
"Entry: $($_.Value) => $($_.Name)"
$OrphanedProfileEntries++
$bOrphaned = $true
}
elseif( -not (Get-ChildItem -Path $_.Key -include ntuser.dat,ntuser.man -Name -Force -File) )
{
"MISSING NTUSER.DAT or NTUSER.MAN: $($_.Value) => $($_.Name)"
$OrphanedProfileEntries++
$bOrphaned = $true
}
if( $bOrphaned -and $bClean )
{
$_.Value.Split( ";") | ForEach-Object `
{
try
{
$WMIUserProfile = gwmi -Class Win32_UserProfile -Filter "sid = '$($_)'"
$WMIUserProfile.Delete()
"Successfully deleted orphaned profile information."
}
catch
{
"Error occurred deleting profile. It may have only been partially deleted. [$($_.Exception.Message)]"
}
}
}
}
"=" * 40
"Orphaned ProfileListEntries: $OrphanedProfileEntries"
#######################################
# Check for Orphaned ProfileGUID entries - having SidString that reference deleted SID keys under ProfileList
# ProfileGUID would only exist on machines that have been domain joined at some time
$ProfileGUIDPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileGUID"
if( Test-Path -Path $ProfileGUIDPath )
{
""
"Looking for orphaned ProfileGUID entries"
"=" * 40
$OrphanedGUIDCount = 0
Get-ChildItem -Path $ProfileGUIDPath | ForEach-Object `
{
$SidString = $null
$SidString = Get-ItemPropertyValue -Path ($ProfilesListRegPath + "\" + $_.PSChildName) -Name "SidString" -ErrorAction SilentlyContinue
if( -not $SidString -eq $null )
{
if( $null -eq (Get-Item ($ProfilesListRegPath + "\" + $SidString) -ErrorAction SilentlyContinue) )
{
"Orphaned GUID: $($_.PSChildName)"
$OrphanedGUIDCount++
if( $bClean )
{
Remove-Item -Path $_.PSPath -Recurse -Force
}
}
}
}
"=" * 40
"Orphaned ProfileGUIDS: $OrphanedGUIDCount"
}
#######################################
# Check for Orphaned user folders - folders in the profile folder that are not referenced by ProfileList\SID keys
""
"Looking for orphaned user folders"
"=" * 40
$KnownUserFolders = @("All Users", "Default", "Default User", "LocalService", "NetworkService", "Public")
$OrhanedUserFolders = 0
Get-ChildItem -Path $ProfilesFolder -Exclude $KnownUserFolders -Directory -Force | ForEach-Object `
{
if( -not $ProfileListInfo.Contains( $_.FullName ) )
{
"Folder: $($_.FullName) (Created: $($_.CreationTime) - Modified $($_.LastWriteTime))"
$OrhanedUserFolders++
if( $bClean )
{
Remove-Item -Path ("\\?\$($_.FullName)") -Force -Recurse
}
}
}
"=" * 40
"Orphaned user folders: $OrhanedUserFolders"
""
"Completed."