# written 7-10-23 [email protected]
# modified 8-10-23 for proper Last used time
# takes into account SentinelOne Canary files and special profiles
write-host "Deleting profiles older than $PurgeOlderThan days"
$UPs=Get-CimInstance -Class Win32_UserProfile | Where-Object {!($_.Special) -and $_.LocalPath -like "*\users\*" -and $_.Localpath -notlike '$*'}
$uparray=@()
foreach ($up in $ups) {
# write-host $up.localpath
$files=gci -path $up.LocalPath -recurse -force -erroraction silentlycontinue -File
if ($files.count -gt 0) {
$NewestFile=(($files | where-object {$_.name -notlike "*.dat" -and $_.FullName -notlike '*afterSentDocuments*'} | Sort-Object -Descending -Property LastWriteTime)[0])
$NewestFileLastWrite=$NewestFile.LastWriteTime
$NewestPretty=$newestFileLastWrite.ToString("MM-dd-yyyy") + " "+$newestfile.fullname
$size = [int](($files | measure-object -property length -sum).sum /1gb)
#$ntuserlastaccesstime=(get-itemproperty -path "$($up.LocalPath)\AppData\Local\Microsoft\Windows\UsrClass.dat" -name LastWriteTime).LastWriteTime
# $uparray+=[pscustomobject]@{Folder=$up.localpath;Windows_Profile=$up.LastUseTime;UsrClassDAT=$ntuserLastAccessTime;GB=$size;NewestFile=$newest}
$uparray+=[pscustomobject]@{Folder=$up.localpath;Size=$size;Count=$files.count;Windows_Profile=$up.LastUseTime;GB=$size;Last_Update=$newestPretty}
}
$ProfileAge= ((Get-Date) - $NewestFileLastWrite).Days
if ($PurgeOlderThan -gt 25 -and $ProfileAge -gt $PurgeOlderThan) {
$x=Get-CimInstance -Class Win32_UserProfile | ? LocalPath -eq $up.localpath | Remove-CimInstance
write-host "Deleted" $up.Localpath "because it was last updated $ProfileAge days ago on" $newestFileLastWrite
}
else {
write-host "Did not delete" $up.localpath "because it's only $profileAge days old"
}
}
$uparray | ConvertTo-HTML
Script data
Language - PowerShell
Run as - System / Root User
Script timeout duration - 30 Mins
Script variables
Run time variables - PurgeOlderThan
Read me
OK - It's well known that delprof2 and even the Microsoft GPO to delete old profiles doesn't work. I wrote this to find out the most recent file edited within a user profile and purge based on THAT date. This will delete profiles older than "PurgeOlderThan" in days, with a >25 day sanity check. (if <25, it won't delete!) As a side benefit, it will also show all profiles and their sizes.