Jump to content

Recommended Posts

Posted

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

Posted
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......
Posted (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 by ChrisMiles
  • Thanks 1
  • 3 weeks later...
Posted
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.

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 account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...