May 25, 2015 Leave a comment
A new twist on a familiar tale is the best way to describe this post! Recently we’d noticed quite a few of our first-gen SSD machines (60GB drives) were running low on disk space, particularly in open-access areas where lots of different users were logging on.
This probably comes as no surprise to most education network admins as it’s something we used to deal with in the days of small HDDs but became almost irrelevant as larger local drives became the norm. To some extent history has repeated itself with SSD drives and we have no such problems with our newer Samsung Evo 120GB drives.
That said a solution still needed to be found for the machines with the 60GB drives. The first port of call was the easy option, enable automatic profile cleanup via GPO after a set period of days:
Computer Configuration > Policies > Administrative Templates > System/User Profiles > Delete user profiles older than a specified number of days on system restart
A bit more thought required
However after thinking about it for a couple of seconds it’s not that easy…
Our domain structure places the Active Directory objects into OUs based on their location (room). Nothing unusual there. However what we don’t know based on OU alone is whether the machine is a classroom PC or one that lives in a staffroom \ office.
This information is very important because our Office 365 Outlook cache, amongst other per-user profile customisations needs to stay persistent and the last thing we want is to wipe staff profiles if the user has been away for a week on holiday!
With that in mind I seemed to have two choices
- Alter the OU structure to split machines into class and admin
This would take a fair bit of administration and ongoing maintenance so wasn’t keen on this option
- Find a way to add some logic to the profile cleanup process
Give the process some intelligence and get it to decide what to do by looking at the machine type
One of the sections in my custom imaging scripts asks the technician what the intended role of the machine is when they start the imaging process (name and location are done at the same time).
This information then goes into a custom registry key I create in HKLM\Software\HCFHE\WorkstationType for future reference.
Then the lightbulb moment: I can use that registry key as the identifier for the profile cleanup. First thought is can I add a WMI filter on the GPO… computer says no (or not easily at least)
Time for some scripting
By this point I’d decided that the GPO on its own wasn’t going to give me enough flexibility so I decided to go down the scripting route instead. First things first, we need a tool to run the profile cleanup, time to dip into my list of handy utilities for the excellent (and free) delprof2:
Not only does it do a thorough job of cleaning profiles but it’s also very flexible in terms of specifying which profiles to clean and runs very nicely from a script :)
The script needs to do a couple of things:
- Check a registry key for the machine type ADMIN, CLASS (or an invalid value) and proceed \ quit accordingly
- Run the delprof2 tool with appropriate switches
- Write output to the Windows Event Log
For some reason I went for VBScript rather than PowerShell this time around. After a bit of research some very handy links turned up some code snippets to use. All credit to the authors for creating and putting them out there for re-use.
The second snippet is particularly useful, having worked with Linux for a while now I was yearning for a Windows equivalent to the “tee” command and very glad that the code below does the same job!
The end result
I’ve included a generalised version of the script below. As always grab the code from my OneDrive public folder to avoid any copy \ paste issues.
- replace REMOVEME with the prefix of accounts to remove i.e. match something consistent in your student account numbers. You can have multiple /id: switches if you have a couple of different patterns to match
- replace LEAVEME with accounts you want to exclude e.g. accounts you may have created for specialist use with profiles that you don’t want to be removed
- You can have multiple /id and /ed switches if you have a range of different account name patterns to match
- change any other delprof2 parameters as required (the example below removes inactive profiles over 7 days old)
- the use of & vbCrLf after each line of output from delprof2 gives a nicely formatted Event Log entry, otherwise everything ends up on one long line!
Const HKEY_LOCAL_MACHINE = &H80000002 strComputer = "." Set objRegistry = GetObject("winmgmts:\\" & _ strComputer & "\root\default:StdRegProv") strKeyPath = "SOFTWARE\HCFHE" strValueName = "WorkstationType" objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue Set shell = CreateObject("WScript.Shell") If IsNull(strValue) Then shell.LogEvent 4, "Machine type registry key not found, exiting without performing profile cleanup" wscript.quit ElseIf strValue="CLASS" Then 'wscript.Echo "The registry key exists, the type is " & strValue Dim objShell Set objShell = WScript.CreateObject( "WScript.Shell" ) Dim strCMD strCMD = """\\yourdomain.tld\netlogon\delprof\DelProf2.exe""" & " /u /d:7 /id:REMOVEME* /ed:LEAVEME*" 'wscript.echo strCMD 'objShell.Run(strCMD) Set objExecObject = objShell.Exec(strCMD) strText = "" Do While Not objExecObject.StdOut.AtEndOfStream strText = strText & objExecObject.StdOut.ReadLine() & vbCrLf Loop shell.LogEvent 4, "Machine type is " & strValue & " - student profile cleanup has been performed" & vbCrLf & strText Set objShell = Nothing wscript.quit ElseIf strValue="ADMIN" Then shell.LogEvent 4, "Machine type is " & strValue & " - profile cleanup not required" wscript.quit Else shell.LogEvent 4, "Machine type is unexpected value " & strValue & ", exiting without performing profile cleanup" wscript.quit End If
The output in the Event Viewer then looks something like this…