Thursday, September 16, 2010

Cleanup Unused User Profiles

Whether it is a terminal server, a loaner laptop, a training machine, or simply a machine that has outlived its owners, user profiles tend to collect on end-user accessed machines consuming system resources with no payback. It is best to address them and keep them addressed before the space they consume causes problems during an application push or other endeavor.

Fortunately, profiles provide a number of clues as to the date they were last used. The easiest one to test for in a script though is the modified date on the NTUSER.DAT file, which is modified at each login and logoff. Unfortunately though, one needs to be an administrator of the local machine to both inspect the profile properties and to delete the profile should it be deemed too old. This can be overcome fairly easily using a tool such as SMS/SCCM or Altiris, scheduled tasks, or some other means.
The script included today is pretty simple. It takes only one argument, which is the number of days that should be used as the threshold whether a profile should be kept or not. It then simply looks up the profile root folder based on what the OS is and proceeds to loop through every profile skipping a few built-in profiles such as the All Users profile.

For example, if you wanted to delete all profiles that had not been used in 60 days, you would simply run:
Cscript profileage.vbs –days 60
Short and sweet.

Script contents below.
on error resume next

Sub Usage()
WScript.Echo UCase(WScript.ScriptName) &_
" - Deletes Profiles based on Age" & vbNewLine & vbNewLine &_
"Enumerates user profiles and displays number of days since" & vbNewLine &_
"last use then deletes those over the specified threshold." & vbNewLine & vbNewLine &_
WScript.ScriptName & " [-DAYS <n>]" & vbNewLine &_
"-DAYS <n> Show only those computers who have not connected in n days" & vbNewLine &_
"-?, -H Displays this help" & vbNewLine & vbNewLine
End Sub

numdays = 0
While i < WScript.Arguments.Count
Select Case Replace(UCase(WScript.Arguments.Item(i)),"/","-")
Case "-DAYS":
Case "-?":
Case else:
End Select
i = i + 1

if numdays < 1 then
wscript.echo "Number of days too low"
wscript.quit -2
end if

key = "HKLM\Software\Microsoft\Windows NT\CurrentVersion\CurrentVersion"

set WshShell = CreateObject("")
if err.number <> 0 then
wscript.echo "unable to create WshShell"
wscript.quit -2
end if

CurVer = WshShell.RegRead (key)
if err.number <> 0 then
wscript.echo "unable to read registry"
wscript.quit -3
end if

Select Case Left(CurVer, 1)
case "4": strProfPath = "c:\winnt\profiles"
case "5": strProfPath = "c:\documents and settings"
case "6": strProfPath = "c:\users"
case else:
wscript.echo "unknown os:" & CurVer
wscript.quit -1
end select

Set FSO = CreateObject("Scripting.FileSystemObject")

Set objDirectory = FSO.GetFolder(strProfPath)

For Each ProfFolder In objDirectory.SubFolders

select case lcase(trim(
case "all users":
case "default user":
Case "localservice":
case "networkservice":
case "system":
case else:
if lcase(left(, 3)) <> "sms" then
Set oFile = FSO.GetFile(strProfPath & "\" & & "\ntuser.dat" )
if err.number <> 0 then
' wscript.echo "unknown file:" & strProfPath & "\" & & "\ntuser.dat"
' wscript.echo err.description

' return how old the file is - SEE NOTE ABOVE.
DaysOld = Int(Now() - oFile.DateLastModified)
     wscript.echo & "is " & DaysOld & " days old."
set oFile = Nothing
if DaysOld > numdays then
fso.DeleteFolder strProfPath & "\" &, True
         if err.number <> 0 then
            wscript.echo "Unable to delete " & strProfPath & "\" &
         end if
     end if
end if
end if
end select

Set objDirectory = Nothing
Set FSO = Nothing
set WshShell = Nothing

No comments:

Post a Comment