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
# 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


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.