Action1 5 Blog 5 How To Delete User Profiles Remotely with PowerShell

How To Delete User Profiles Remotely with PowerShell

Published:
August 1, 2026
Last Updated:
August 3, 2026

By Peter Barnett

First 200 endpoints free, no feature limits.

No credit card required, full access to all features.

TL;DR

  • Recommended method: Query Win32_UserProfile with Get-CimInstance and delete selected profiles with Remove-CimInstance.
  • Why CIM deletion is safer: It removes the profile folder, unloads the user registry hive, and clears the related ProfileList SID reference.
  • Avoid folder-only deletion: Remove-Item deletes files but can leave orphaned registry and profile records that cause temporary-profile or logon errors.
  • Filter by name: Match LocalPath or derived usernames to target temporary, student, lab, contractor, or training profiles.
  • Filter by age: Compare LastUseTime with a configurable cutoff, such as 30, 60, or 90 days.
  • Protect active profiles: Always exclude profiles where Loaded is true.
  • Protect system profiles: Exclude profiles marked as Special, including Default, Public, SystemProfile, LocalService, and NetworkService.
  • Protect critical accounts: Maintain exclusion lists for administrators, service accounts, help-desk users, and specific SIDs.
  • Remote cleanup: Use Get-CimInstance with remote computer names or PowerShell remoting to process multiple endpoints centrally.
  • Test before deletion: Add WhatIf behavior, logging, or confirmation steps and validate the script against a small pilot group.
  • Use centralized logging: Record processed computers, deleted profiles, skipped profiles, failures, usernames, and last-use dates.
  • Handle unreachable devices: Wrap remote operations in try/catch logic so one offline computer does not stop the entire cleanup run.
  • WMIC is deprecated: Replace legacy WMIC commands with modern CIM cmdlets and PowerShell remoting.
  • GUI option: Use Advanced System Properties for occasional deletion of one or two profiles on a local computer.
  • Reimage when appropriate: Reimaging may be more efficient when nearly every profile must be removed or the workstation may contain wider system-level problems.

Removing Windows user profiles on shared workstations requires targeting the operating system’s registration mechanism rather than just deleting profile folders from the file system. PowerShell is the most reliable method for deleting user profiles, especially when administrators need to remove multiple profiles or automate the process across many endpoints. Rather than manually deleting profiles through system properties, PowerShell interacts directly with the Win32_User profile WMI/CIM class, which exposes each profile as a manageable object. Using this class allows administrators to identify, filter, and safely delete user profiles while protecting important system accounts. PowerShell is especially useful for common administrative tasks such as removing temporary user profiles, cleaning up inactive accounts on shared workstations, reclaiming disk space, or preparing lab and kiosk machines for new users. For example, a school lab administrator utilizes a PowerShell script based on the Win32_UserProfile class to automatically remove old student profiles from every classroom PC after each semester.

Script logic — filter target profiles, then loop & delete

A reliable profile cleanup script usually follows three-step logic, regardless of the environment. First, retrieve all local user profiles from the Win32_UserProfile class using either Get-CimInstance or Get-WMIObject, then apply one or more filters to target specific profiles, such as matching a username prefix or how long a profile has been inactive. Filters select specific profiles, and exclusion criteria protect admin and service accounts, system accounts, or the currently logged-in user. On the last stage before deleting any profile, the exclusion list is validated, and profiles matching the filter are deleted.

A production-ready script first identifies eligible profiles, loops through each profile to match according to the filter, and ensures that exclusion criteria are also met (i.e., admin, service accounts, or the current user is not in scope), then deletes target profiles individually. Administrators can also add logging, confirmation prompts or a “WhatIf” mode so they can review which profiles would be deleted before making permanent changes.

Filter profiles by name/prefix or age threshold

PowerShell scripts typically use one of two filtering methods to determine which user profiles should be removed, i.e., name-based filtering or age-based filtering. Both methods retrieve profile information from the Win32_UserProfile class using Get-CimInstance or Get-WmiObject. Filtering by naming pattern targets temporary accounts better by matching string values in the local path property. Administrators use this approach in environments where temporary users, contractors, students, or training accounts share a consistent prefix such as std-01, temp-user-1, or labuser-01. On the other hand, age-based filtering leverages the LastUseTime property to calculate the days since a user last signed off to identify inactive accounts. The script checks the LastUseTime property exposed by Win32_UserProfile and compares it against a configurable value such as 30, 60, or 90 days. Profiles exceeding the inactivity threshold are marked for deletion, making this approach ideal for routine monthly or quarterly lab maintenance.

Both Get-CimInstance and Get-WmiObject query the Win32_UserProfile class and return the same profile information. Get-CimInstance is the preferred cmdlet because it uses the newer WS-Management protocol, supports PowerShell remoting more efficiently, and is the recommended way in modern Windows administration.

Example

PowerShell

# Identify profiles starting with ‘Temp’ OR inactive profile for more than 30 days

$ThresholdDate = (Get-Date).AddDays(-30)

$StaleProfiles = Get-CimInstance -ClassName Win32_UserProfile | Where-Object {

    ($_.LocalPath -like “*\Temp*”) -or

    ($_.LastUseTime -and $_.LastUseTime -lt $ThresholdDate)

}

 

 

Delete via CIM/WMI (Win32_UserProfile + Remove-WmiObject/Remove-CimInstance)

Deleting a profile through the Win32_UserProfile class is the recommended method because, in this way, Windows properly unloads the user registries, i.e., NTUSER.DAT, and clears the corresponding Security Identifier (SID) entry from ProfileList before removing files and folders. Manually deleting the User profile folders cannot cleanup registries and SID references. It is important to clean up SID references, as an orphaned ProfileList SID is the direct cause of the error “The User Profile Service Failed the Logon,” which is one of the common reasons for temporary profile creation. A production-ready script should include multiple exclusion checks before performing the profile delete process. Exclusion checks must include logic to exclude special accounts, i.e., “Special -eq $true” to exclude built-in profiles such as Default, Public, SystemProfile, LocalService, NetworkService. The script should also exclude known administrative or service accounts such as Administrator, or service accounts for other software like NT Service\MSSQLServer (SQL Server) and IIS_IUSRS (IIS). Script should be able to skip any profile that is currently logged in to the system with a filter like “Loaded -eq $true”.
Modern Scripts should use Get-CimInstance together with Remove-CimInstance, while in legacy environments, Get-WmiObject with Remove-WmiObject commands are utilized.

Example PowerShell script:

# Query local profiles, apply strict exclusion logic, and safely delete via Remove-CimInstance

Get-CimInstance -ClassName Win32_UserProfile | Where-Object {

    $_.Special -eq $false -and

    $_.Loaded -eq $false -and

    $_.LocalPath -notlike “*\Administrator” -and

    $_.LocalPath -notlike “*\Public”

} | Remove-CimInstance -Confirm:$false

 

Delete via Remove-Item on the folder (naive method)

Directly targeting and deleting a profile folder under the “C:\Users\…” path using the Remove-Item command seems to be a shortcut approach, but it only removes the files and folders on disk and leaves the registry hive reference under “HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList” and the SID entry in ProfileList completely intact. Windows continues to believe that profile still exists, which can cause profile loading errors, temporary profile creation, or failed logons for these users. Moreover, after Windows 10 version 1909 and later, this scenario has been documented to break the start menu and Cortana/Search functionality, not just for removed profiles but for other profiles on the shared machine. For example, an administrator runs “Remove-Item -Path “C:\Users\Rayan201” -Recurse -Force” to delete the profile folder of a departed employee to free up some space quickly, may find the next day that every other user on that shared workstation reports a broken or blank Start menu issue.

Manual GUI/CLI method (no script)

The native Windows Graphical User Interface (GUI) provides a built-in utility and command-line tools, specifically designed to safely and completely remove an individual user profile. Although these methods require more user interaction than a scripted solution, they are suitable for occasional maintenance or troubleshooting of single workstations, but they become inefficient when managing multiple shared workstations. Unlike the PowerShell Win32_UserProfile class method, manual approaches require administrators to perform cleanup steps individually on each workstation; particularly, the Command Prompt method requires separate steps to remove the user account, delete the profile folder, and manually clean up the associated registry entry. Missing any of these steps can leave orphaned profile references that may cause unexpected profile loading errors or creation of temporary profiles.

System > Advanced System Properties > User Profiles (GUI)

Windows provides a dedicated profile management panel under System Properties, which can be opened from the Run dialog box using “sysdm.cpl”. After that, move to the “Advanced” tab and click on “User Profiles” settings. Choose the profile you want to remove, apart from the logged-in user, and click the Delete button.

This approach is ideal for administrators who only need to remove one or two profiles on a local machine and prefer a quick graphical user interface. Because each profile must be selected manually and one by one, it is not practical for environments with hundreds of workstations.

net user /delete + rd /s /q + registry ProfileList SID cleanup

When using the Command Prompt instead of PowerShell, deleting the user account alone is not enough to completely remove the user profile. This approach involves three separate tasks: deleting the local account, removing the profile folder from disk, and deleting the corresponding ProfileList registry entry.

  1. Open a Command Prompt with administrative privileges and run the following command to delete the user:
    net user testuser1 /delete
  2. Now remove the profile folder of the deleted user:

rmdir /s /q “C:\Users\testuser1”

  • Open the Registry Editor by running the regedit run dialog box, navigate to the following registry path “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList”, traverse through each SID subkey, and look at the “ProfileImagePath” value on the right pane. Find the key where “ProfileImagePath” matches the delete user e.g. “C:\Users\testuser1”. After that, right-click that SID subkey and delete

Bulk / remote deletion across many machines

Removing user profiles manually on a single Windows workstation is straightforward, but in enterprise environments administrators often need to remove multiple profiles from dozens or hundreds of endpoints regularly. In organizations with shared workstations, training labs, kiosks, hospitals, and manufacturing environments, manually logging into each computer becomes impractical and inefficient. Bulk profile deletion through PowerShell combines remote management tools, automated scripting, and centralized logging so administrators can perform profile cleanup consistently across the entire environment on regular intervals. Before deploying a bulk profile deletion script, administrators should always validate the script on a small pilot group of computers and always use exclusion criteria to protect profiles logged on to remote computers, service accounts, admin accounts, and system profiles.

Administrators commonly face this challenge and question why not just reimage the operating system when they have to delete lots of profiles. For example, in the case of a college lab administrator who needs to delete students’ profiles after every semester, why not just reimage the OS and wipe the slate clean for next semester? Deciding between removing profiles vs reimaging the OS comes down to the affected systems radius vs how quickly recovery can happen. If lots of profiles are in a corrupt state, most of the profiles will be removed anyway, or whether the scope of profile removal is all profiles on a workstation and, most importantly, none of the profiles are permanent, then reimaging is the better choice. Because profile deletion only removes user-specific data and settings, it does not affect shared local applications, drive mappings configured at the machine level, or persistent malware, rootkits, or unauthorized system-level modifications. Profile deletion is suitable when a limited number of profiles are in scope, i.e., some users have experienced issues, and other users’ profile retention is a requirement. Profile deletion is quick, it’s more precise, and it has negligible impact on other users.

wmic + SID filter, remote NODE targeting

Network administrators traditionally relied on the Windows Management Instrumentation Command Line Utility to target remote endpoints through “/Node:HOSTNAME” switch and forcefully remove user profiles matching a specific Security Identifier (SID). Wmic allows administrators to run WMI queries on remote computers to delete specific profiles without a remote desktop session or physical access.

For example, “wmic /node:”WKS-042″ /nointeractive path Win32_UserProfile where “SID=’S-1-5-21-3623811015-3361044348-30300820-1001′” delete”. However, Microsoft has officially deprecated wmic, and it’s recommended to use PowerShell scripting to delete user profiles on remote computers. Using PowerShell, the same SID in the wmic command can be deleted as well:

“Get-CimInstance -ComputerName “WKS-042” -ClassName Win32_UserProfile -Filter “SID = ‘S-1-5-21-3623811015-3361044348-30300820-1001′” | Remove-CimInstance”

Microsoft recommends using PowerShell with CIM cmdlets or PowerShell Remoting, which provides better error handling, authentication options, and a complete automated solution. A PowerShell remoting approach generally follows this workflow:

  1. Connect to the remote computer using Invoke-command
  2. Retrieve the target profile(s) with Get-CimInstance Win32_UserProfile.
  • Filter the profile with a naming pattern, age or SID
  1. Pipe the filtered profile object directly into the Remove-CimInstance cmdlet (ensuring it is not currently loaded).

Remove Inactive User Profiles Using PowerShell

# Remote computers to process

$Computers = @(

    “PC001”,

    “PC002”,

    “PC003”

)

 

# Delete profiles unused for more than this many days

$AgeInDays = 90

$CutoffDate = (Get-Date).AddDays(-$AgeInDays)

 

# Delete only usernames matching this regex pattern

# Examples:

# “^Student”, “^Temp”, “^LAB”, “.*” (all users)

$UserNamePattern = “^Student”

 

# Additional usernames to exclude, beyond the built-in/system accounts

$ExcludedUsers = @(

    “HelpDesk”,

    “SQLAdmin”,

    “TrainingAdmin”,

    “ServiceUser”

)

 

# Explicit SIDs to always exclude, regardless of username or pattern matches.

# Useful for accounts whose username can’t be resolved (orphaned SIDs) or for

# protecting specific known profiles across all target computers.

# Example: “S-1-5-21-1234567890-1234567890-1234567890-1001”

$ExcludedSIDs = @()

 

# Only consider profiles whose SID matches this regex pattern. Defaults to

# matching everything; narrow it down to target a specific domain or SID

# range, e.g. “^S-1-5-21-1234567890-1234567890-1234567890-” for one domain.

$SIDPattern = “.*”

 

# Where to write the log file (created if it doesn’t exist)

$LogDirectory = “C:\Logs\ProfileCleanup”

$LogFile = Join-Path $LogDirectory (“ProfileCleanup_{0}.log” -f (Get-Date -Format “yyyyMMdd_HHmmss”))

 

# ———————————————

# Logging helper

# ———————————————

 

function Write-Log

{

    param(

        [Parameter(Mandatory)]

        [string]$Message,

 

        [ValidateSet(“INFO”, “WARN”, “ERROR”)]

        [string]$Level = “INFO”

    )

 

    $timestamp = Get-Date -Format “yyyy-MM-dd HH:mm:ss”

    $line = “[{0}] [{1}] {2}” -f $timestamp, $Level, $Message

 

    switch ($Level)

    {

        “WARN”  { Write-Warning $Message }

        “ERROR” { Write-Host $line -ForegroundColor Red }

        default { Write-Host $line -ForegroundColor Cyan }

    }

 

    # Best-effort file logging; don’t let a logging failure stop the run

    try

    {

        Add-Content -Path $LogFile -Value $line -ErrorAction Stop

    }

    catch

    {

        Write-Warning “Could not write to log file ‘$LogFile’: $_”

    }

}

 

# Ensure the log directory exists before the run starts

if (-not (Test-Path $LogDirectory))

{

    New-Item -Path $LogDirectory -ItemType Directory -Force | Out-Null

}

 

# ———————————————

# Main

# ———————————————

 

Write-Log “Starting profile cleanup run. AgeInDays=$AgeInDays, UserNamePattern=’$UserNamePattern’, SIDPattern=’$SIDPattern'”

 

$Summary = [ordered]@{

    ComputersProcessed = 0

    ComputersFailed    = 0

    ProfilesDeleted    = 0

    ProfilesSkipped    = 0

}

 

foreach ($Computer in $Computers)

{

    Write-Log “Processing $Computer…”

 

    try

    {

        $Profiles = Get-CimInstance -ClassName Win32_UserProfile -ComputerName $Computer -ErrorAction Stop

        $Summary.ComputersProcessed++

 

        foreach ($Profile in $Profiles)

        {

            # Skip profiles that are currently loaded or marked as special

            if ($Profile.Loaded -or $Profile.Special)

            {

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Exclude explicitly listed SIDs

            if ($ExcludedSIDs -contains $Profile.SID)

            {

                Write-Log “SID ‘$($Profile.SID)’ on $Computer is in the exclusion list; skipping.”

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Apply SID pattern filter

            if ($Profile.SID -notmatch $SIDPattern)

            {

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Derive username from the profile’s local path

            try

            {

                $UserName = Split-Path -Path $Profile.LocalPath -Leaf

                if ([string]::IsNullOrWhiteSpace($UserName))

                {

                    throw “LocalPath ‘$($Profile.LocalPath)’ did not yield a usable username.”

                }

            }

            catch

            {

                Write-Log “Could not derive username from LocalPath ‘$($Profile.LocalPath)’ on $Computer; skipping. $_” -Level WARN

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Exclude built-in and system-critical accounts

            if ($UserName -match ‘^(Administrator|Default|Default User|Public|All Users)$’)

            {

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Exclude service accounts

            if ($UserName -match ‘^(SYSTEM|LOCAL SERVICE|NETWORK SERVICE)$’)

            {

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Exclude custom usernames

            if ($ExcludedUsers -contains $UserName)

            {

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Apply username pattern filter

            if ($UserName -notmatch $UserNamePattern)

            {

                $Summary.ProfilesSkipped++

                continue

            }

 

            # Apply age filter

            if ($Profile.LastUseTime -gt $CutoffDate)

            {

                Write-Log “Profile ‘$UserName’ on $Computer last used $($Profile.LastUseTime); within retention window, skipping.”

                $Summary.ProfilesSkipped++

                continue

            }

 

            Write-Log “Deleting profile ‘$UserName’ on $Computer (last used: $($Profile.LastUseTime))”

 

            try

            {

                Remove-CimInstance -InputObject $Profile -ErrorAction Stop

                $Summary.ProfilesDeleted++

            }

            catch

            {

                Write-Log “Failed to delete profile ‘$UserName’ on $Computer. $_” -Level ERROR

            }

        }

    }

    catch

    {

        $Summary.ComputersFailed++

        Write-Log “Failed to process $Computer. $_” -Level ERROR

    }

}

 

Write-Log (“Run complete. Computers processed: {0}, failed: {1}. Profiles deleted: {2}, skipped: {3}.” -f `

    $Summary.ComputersProcessed, $Summary.ComputersFailed, $Summary.ProfilesDeleted, $Summary.ProfilesSkipped)

Write-Log “Log file written to: $LogFile”

#…………………………………………………………………………………………………………………………….

Common Errors and How To Fix Them

When system administrators try to clean up Windows user profiles, manually or through scripts, they often encounter persistent errors that require systematic troubleshooting. Many of these problems occur because Windows stores profile information in multiple locations, including the file system, registry, and WMI/CIM database, not just in the profile folder, i.e., “C:\Users\profilefolder”. Simply deleting the profile directory leaves behind registry entries, Security identifiers (SIDs) or application data that can cause login issues and orphaned profiles. Administrators must always use tested scripts for profile management, such as using the Win32_UserProfile CIM/WMI class or the User Profile Management interface in System Properties. Another common confusion occurs from the use of Third-party cleanup utilities such as Delprof2 that have been used widely for automated profile cleanup. Administrators should understand that third-party utilities have their own limitations or known issues as well, such as a well-known issue with Delprof2 where it may report or rely on an inaccurate “Last Used time stamp” value, making age-based cleanup less reliable. Chaining Delprof2 with a custom age-based cleanup script introduces risk of profiles being flagged as recently used, because Delprof2 may reset a profile LastUseTime registry value after processing it.
Whenever troubleshooting profile deletion issues, administration should always verify whether the profile is currently loaded in the OS, confirm sufficient administrative permissions for the account executing the script, and review Windows Event Viewer for profile service errors. Test the automation script on a pilot machine before deploying it across multiple endpoints to avoid issues on a large scale.

“Access denied” when deleting AppData under a profile folder

One of the most common errors administrators encounter is “Access Denied” when attempting to delete folders inside “AppData” after removing a user account. It usually occurs because some of the files in the profile’s AppData folder are opened in any running processes, Windows services, antivirus software, search indexing, or background applications. Even when the user has logged off, Windows may still maintain file handles that prevent individual files or folders from getting deleted. Because of this, it is recommended not to delete the profile folder manually or with “Remove-Item” but to use the Win32_UserProfile class through CIM/WMI. Calling Remove-CimInstance does not just delete files; it goes through the same profile unloading sequence Windows uses when a profile is properly retired, which releases open handles against files and folders from active processes and unloads the registry hive, i.e., NTUSER.DAT, before removing anything from the disk.

If an administrator must delete a profile folder, for example, when cleaning up residue after a failed profile removal, they should first ensure that the profile is completely unloaded and run the delete process from an elevated Command Prompt or PowerShell session. Verify that no processes are using files within the profile folder, and if necessary, take ownership of the folder and grant administrative permissions before attempting the delete process. In some cases, if the Access is denied issue persists, restarting the computer or deleting the folder from Windows Safe Mode may be required.

Start menu breaks after deleting a profile folder directly

Since Windows 10 version 1909 and later, administrators have notices issues where the start menu, search functionality stop working after profiles are removed by simply deleting the profile folders from “c:\Users\profilefolders” location. These issues occur because the operating system retains reference of deleted profile folders in registry path “HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList” , WMI/CIM objects, and profile service metadata.”. Now when the next user who logs into a rebuilt or reused profile on that workstation can end up with a start menu opening failure, blank tile layout or error when clicking on start menu.

The recommended way to remove profile is by using Win32_USerProfile class with CIM commands method through PowerShell or from System properties interface. These methods not only delete the profile folder but also remove the associated registry entries and profile records, ensuring that windows fully remove the profile traces.

 

See What You Can Do with Action1

 

Join our weekly LIVE demo “Patch Management That Just Works with Action1” to learn more

about Action1 features and use cases for your IT needs.

 

spiceworks logo
getapp logo review
software advice review
trustradius
g2 review
g2 review