Detect and purge old or orphaned profiles

Mon Jan 09 2023
# Properties to define
$DateThreshold = (Get-Date).AddDays(-60)

# Clear all profiles not used within threshold
$Profiles = Get-CimInstance Win32_UserProfile
$OldProfiles = $Profiles | Where-Object { $_.LastUseTime -lt $DateThreshold }
Write-Host "Removing $($OldProfiles.Count) profiles which haven't been used for 60+ days .."
$OldProfiles | Remove-CimInstance

# Clear any orphaned profiles
$ProfileListHive = 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionProfileList'
$ProfilesRegistry = Get-ChildItem $ProfileListHive
$ActiveProfiles = $ProfilesRegistry | ForEach-Object { $_.GetValue('ProfileImagePath') }
$FolderProfiles = Get-ChildItem 'C:Users' -Directory | `
    Where-Object { $_.Name -ne 'Public' } | `
    Select-Object -ExpandProperty FullName
$OrphanFolders = Compare-Object $ActiveProfiles $FolderProfiles | `
    Where-Object { $_.SideIndicator -eq '=>' } | `
    Select-Object -ExpandProperty InputObject

Write-Host "Removing $($OrphanFolders.Count) folders from C:Users which aren't associated with a Profile in the registry .."
foreach ($OrphanFolder in $OrphanFolders) {
  takeown /F $OrphanFolder /R /SKIPSL
  icacls $OrphanFolder /grant "$env:USERDOMAIN$($env:USERNAME):(F)" /T
  Remove-Item $OrphanFolder -Recurse -Force
}