Removing Windows User Profiles
Just a quick one for today. I'm going through a bunch of laptops which have loads of old directories in C:\Users, in the form of Username, Username.Domain, Username.Domain.000, 001 etc. Most of these don't exist as profiles if you query CIM for win32_userprofile (and aren't in the registry at the HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList.
So I've knocked up a script which goes through the "official" profile list, deletes everything that isn't System/LocalService/NetworkService or the user running the script, and then goes through clearing anything that is left on disk (excluding the above plus the Public folder).
Only issues I have so far is where I get access denied on the odd folder, or very long path names but they seem to be a small minority at the moment.
# Script to delete local profiles
# Exclude well known profiles systemprofile,LocalService,NetworkService and currently logged on user
# Also clear up any rubbish left behind by old profile deletions that didn't clear the disk
#
# Katy Nicholson 13/07/2020
# katystech.blog
# Loop through all profiles reported by system and remove, then if any directories have been left behind, get rid of them too
$Profiles = Get-CimInstance -ClassName win32_userprofile
$Profiles | ForEach-Object {
if (-not ($_.SID -in @("S-1-5-18", "S-1-5-19", "S-1-5-20", (([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value)))) {
Write-Host "Removing Profile for" ((New-Object System.Security.Principal.SecurityIdentifier($_.SID)).Translate([System.Security.Principal.NTAccount]).value)
$_ | Remove-CimInstance
if (Test-Path $_.LocalPath) {
Write-Host "++ Deleting leftover directory"
Remove-Item -Recurse -Force $_.LocalPath
}
}
}
# Loop through remaining directories in c:\users and delete anything that isn't Public or (Current User)
$CurrentUserProfile = Get-CimInstance -ClassName win32_userprofile | Where{$_.SID -eq (([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value)}
Get-ChildItem "C:\Users" | ForEach-Object {
if (-not ($_.Name -in @("Public", "Default", (Split-Path -Leaf $CurrentUserProfile.LocalPath)))) {
Write-Host "Deleting old directory" $_.Name
Remove-Item -Recurse -Force $_.FullName
# Big problem when we hit folders we can't delete - so take ownership of whatever didn't delete and try again.
if (Test-Path $_.FullName) {
Write-Host "++Taking ownership..."
takeown.exe /F $_.FullName /R /D Y | Out-Null
Write-Host "++Attempting deletion stage 2"
Remove-Item -Recurse -Force $_.FullName
}
}
}