Delete Old User Profiles Using GPO or Manually
How to Delete a User Profile Manually in Windows?
Many novice Windows admins try to manually delete a user profile folder from C:Users. You can do it if after manually deleting the folder, you will delete the user profile section with the link to this folder from the registry key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\ProfileList.
The correct way to manually delete a user profile in Windows is to open System Properties, go to Advanced System Settings -> User Profiles -> Settings, select a user in the list (the Size column shown the size of the profile on the local drive) and click the Delete button.
But this is a manual method, and you may want to automate it.
GPO: Delete User Profiles Older Than a Specified Number Days
In Windows, there is a built-in Group Policy to automatically delete user profiles older than xx days. You can find the policy Delete user profiles older than a specified number days on system restart in the GPO section Computer Configuration -> Administrative Templates -> System -> User Profiles. You can enable this policy in the Local Group Policy Editor (gpedit.msc) or using domain policies in GPMC.msc. Enable the policy and specify the number of days a user profile is considered active. When this period is over, Windows user profile service will automatically delete the profile at the next restart. It is recommended to specify the period of 45-90 days here.
When using this policy, make sure that when a server is shut down or restarted there are no problems with the system time. Otherwise active user profiles may be deleted.
The main troubles associated with this automatic method of profile removal is waiting for the server restart and non-selectivity (you cannot prohibit deleting certain user profiles like local accounts, administrative accounts, etc.). Also, this policy may not work if some third-party software (most often it is an antivirus) accesses NTUSER.DAT file in user profiles and updates the date of last use.
PowerShell Script to Delete Old User Profiles in Windows
Instead of using the automatic cleanup profile policy described above, you can use a simple PowerShell script to find and remove profiles of disabled or inactive users. First of all, let’s try to count the size of all user profil folders in C:Users using a simple script from the article Getting Directory Sizes in PowerShell:
1 2 3 4 5 6 7 |
gci -force 'C:Users'-ErrorAction SilentlyContinue | ? { $_ -is [io.directoryinfo] } | % { $len = 0 gci -recurse -force $_.fullname -ErrorAction SilentlyContinue | % { $len += $_.length } $_.fullname, '{0:N2} GB' -f ($len / 1Gb) $sum = $sum + $len } “Total size of profiles”,'{0:N2} GB' -f ($sum / 1Gb) |
The total size of all user profiles in C:Users is 31,5 GB.
Let’s display the list of users, whose profiles has not been used for more than 60 days. To find them, you can use the value in the LastUseTime field of the profile.
1 |
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-60))}| Measure-Object |
It turned out that I had 127 inactive user accounts on my RDS host (with a profiles total size of about 18 GB).
To remove all these profiles, it is enough to redirect the user list to the Remove-WmiObject command (prior to running the script, it is recommended to double-check its output using the –WhatIf parameter):
1 |
Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and (!$_.Loaded) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-30))} | Remove-WmiObject –WhatIf |
In order not to delete profiles of some users, like System and Network Service accounts, a local administrator account, accounts of users having active sessions, account exception list), you can modify the script as follows:
1 2 3 4 5 6 7 8 9 10 11 |
#The list of accounts, which profiles must not be deleted $ExcludedUsers ="Public","zabbix_agent","svc",”user_1”,”user_2” $LocalProfiles=Get-WMIObject -class Win32_UserProfile | Where {(!$_.Special) -and (!$_.Loaded) -and ($_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-60))} foreach ($LocalProfile in $LocalProfiles) { if (!($ExcludedUsers -like $LocalProfile.LocalPath.Replace("C:\Users\",""))) { $LocalProfile | Remove-WmiObject Write-host $LocalProfile.LocalPath, "profile deleted” -ForegroundColor Magenta } } |
You can run this PowerShell script using a GPO at shutdown or with a PoSh script in Task Scheduler.
Before configuring automatic deletion of profiles, it is recommended to test the script in your environment!
You can modify the script to automatically remove all user profiles added to the specific AD group (for example, DisabledUsers group):
1 2 3 |
$users = Get-ADGroupMember -Identity DisabledUsers | Foreach {$_.Sid.Value} $profiles = Get-WmiObject Win32_UserProfile $profiles | Where {$users -eq $_.Sid} | Foreach {$_.Delete()} |