Sir Posted March 8, 2019 Posted March 8, 2019 Hello all, I need to be able to delete user profiles AND the local profile folders. We have shared PC's like in most schools and since using 256 ssd's, after a while disk space gets full. We have a policy for removing profiles older than x days with GP's but the issue is the space taken up by the C:\Users\username. What i would like to do is remove all folders beginning with a number as all our students start with the year of intake and staff and admins profiles do not. Any suggestions. This disk space issue must affect more than me surely but searches on the web are not very helpful so far with scripts all saying to users to remove , etc.! Cheers all, Sir
jthompson Posted March 8, 2019 Posted March 8, 2019 (edited) There's an MS utility called delprof that you can do this with. Have a search across EduGeek for some example usage, as plenty will have it running from a shutdown/startup script to do exactly what you've described. EDIT: whilst originally an MS utility, you'll want this instead - https://helgeklein.com/free-tools/delprof2-user-profile-deletion-tool/ Edited March 8, 2019 by jthompson 1
TriggerHappyUK Posted March 8, 2019 Posted March 8, 2019 We use Delprof to remove profiles completely. Works a treat. We're going to set it up as a startup script in the near future 1
Sir Posted March 8, 2019 Author Posted March 8, 2019 OMG i used this years ago, had issues with early win 10, scrapped it... but that now works a treat! you are both great indeed! Thanks again- love iiiiiiiitttttt......
ChrisMiles Posted March 8, 2019 Posted March 8, 2019 (edited) This exert from our powershell startup script takes care of this. We also have a field in AD that we can set with a data to force delete a user's profile before a certain date when their profile needs resetting for any reason. You won't probably be able to copy and paste this as is but you could adapt it to your uses. It's very reliable, has run here with no issues for 2 years. ###################################################################################################################################################### ## PERFORM USER PROFILE CLEANUP ## ###################################################################################################################################################### ## Clean up user profiles, remove expired profiles and invalid directories. ## ###################################################################################################################################################### Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Performing user profile cleanup..." # Read user profiles from WMI Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Reading user profile information from WMI..." [array]$profiles = Get-WmiObject -Class Win32_UserProfile Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - $($profiles.Count) user profiles found." # Loop through each profile foreach ($profile in $profiles) { try { # If the profile is loaded and currently in use or a special # profile used by windows we should skip it. if ($profile.Loaded -ieq "True" -or $profile.Special -ieq "True" -or $profile.LocalPath.EndsWith("\\User")) { continue; } # If the profile has status 1 it is a temporary profile created # when a roaming profile was not available and should be deleted if ($profile.Status -eq 1) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the value of Status is 1 (Temporary)..." $profile.Delete() continue; } # If the profile has status 4 it is a mandatory profile and # can be deleted to free up space if ($profile.Status -eq 4) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the value of Status is 4 (Mandatory)..." $profile.Delete() continue; } # If the profile has status 8 windows believes it to be # corrupt and should be deleted if ($profile.Status -eq 8) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the value of Status is 8 (Corrupted)..." $profile.Delete() continue; } # Search Active Directory for the owner of this profile $user = ([adsisearcher]"(objectSid=$($profile.SID))").FindOne() # If the owner no longer exists the profile should be deleted if ($user -eq $null) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the user with SID '$($profile.SID)' no longer exists..." $profile.Delete() continue; } # If the profile has status 0 it is most likely a local profile created # when a user logs in without a roaming profile. We should check if this # profile belongs to a student user, and if so delete it. if ($profile.Status -eq 0 -and $user.Properties.description -ne $null -and $user.Properties.description[0].Contains("Students")) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the value of Status is 0 (Local) and the owner '$($user.Properties.samaccountname)' is a student..." $profile.Delete() continue; } # If the profile's folder has a domain suffix it should be deleted if ((Split-Path -Leaf $profile.LocalPath) -ine $user.Properties.samaccountname) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the folder name '$(Split-Path -Leaf $profile.LocalPath)' does not match the value of SamAccountName '$($user.Properties.samaccountname)'..." $profile.Delete() continue; } # Get the date and time the profile was last used if ($profile.LastUseTime -ne $null) { $lastUsedDateTime = $profile.ConvertToDateTime($profile.LastUseTime) } elseif ($profile.LastUseUploadTime -ne $null) { $lastUsedDateTime = $profile.ConvertToDateTime($profile.LastUploadTime) } else { $lastUsedDateTime = [DateTime]::MinValue } # Parse the expiration date from the owner user's Active Directory # Account and if it is after the time the profile was last used # the profile should be deleted [long]$profileExpiryTime = 0 if ([long]::TryParse($user.Properties.info, [ref] $profileExpiryTime) -and $lastUsedDateTime -le [datetime]$profileExpiryTime) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the value of LastUploadTime '$lastUsedDateTime' is less than the value of ProfileExpiryTime '$([datetime]$profileExpiryTime)'..." $profile.Delete() continue; } [datetime]$nowDateTime = Get-Date [timespan]$profileExpiryAge = [timespan]::FromDays(14) if (($nowDateTime - $lastUsedDateTime) -gt $profileExpiryAge) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging profile at '$($profile.LocalPath)' because the time difference between now '$nowDateTime' and the value of LastUploadTime '$lastUsedDateTime' is greater than the value of ProfileExpiryAge '$($profileExpiryAge)'..." $profile.Delete() continue; } } catch { Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Error: $_" } } # Get a list of folders in the profile directory excluding those # known to be a normal part of Windows Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Reading profile folder information..." [array]$folders = Get-ChildItem -Path C:\Users -Exclude Public, "All Users", Default, "Default User" | Where-Object { $_.PSIsContainer } Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - $($folders.Count) profile folders found." # Loop through each folder foreach ($folder in $folders) { try { # If the folder is not associated with a user profile # then the folder should be deleted. if (($profiles | Select-Object -ExpandProperty LocalPath) -inotcontains $folder.FullName) { Write-Output "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Purging folder at '$($folder.FullName)' because it is not associated with any user profiles..." $folder.Delete($true) } } catch { Write-Error "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") - Error: $_" } } Edited March 8, 2019 by ChrisMiles 1
MYK-IT Posted March 8, 2019 Posted March 8, 2019 We use Delprof2 https://helgeklein.com/free-tools/delprof2-user-profile-deletion-tool/
Zourous Posted March 26, 2019 Posted March 26, 2019 I would like to achieve the same thing as the OP but on doing some tests I realise that deleting profiles of a certain age is a bit unreliable with delprof2. I've downloaded the newest version and also tried the NTUSER.INI switch but it is still suggesting to delete profiles that shouldn't be deleted going by the date modified stamp on the username's folder.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now