In the first part of this two-part article, our guest expert Mark Van Noy began by explaining what the problem is with managing persistent profiles. Mark then outlined some common approaches for managing persistent user profiles including:
- Mandatory Profiles
- Guests Group Account
- Deep Freeze and similar products
- Deleting the profile
- Virtual Desktop Infrastructure (VDI)
In this second part, Mark describes a custom approach he developed for managing the persistent user profiles needed for the labs at his university. We once again would like to express our thanks and appreciation Mark Van Noy, who is a Technical Lead/Architect at the University of Colorado Boulder in the Greater Denver area and who has contributed some of his hard-earned technical expertise for the benefit of all our readers.
Mark Van Noy's custom solution
"For our physical labs, the cleanest solution was to have profiles deleted whenever someone logged off the computer. However, with Windows 7 and later there was no solution that we could find that would do that. So we ended up writing our own service in C# that deletes profiles on logoff. To make administration easier we use a configuration file that the service reads when it starts and contains a list of accounts that should not be deleted. We place our administrative accounts into the configuration file while leaving our least-privilege accounts out of the configuration so that our profiles stick around when administrative logins are used, and we have the same experience as our end users when using our normal day-to-day accounts.
"The service worked well for Windows 7. Since it was a service, it could delete the user accounts as no one was actually logged in to lock any of the files, such as the NTUSER.dat, that would otherwise prevent the profile from being deleted. The service runs as SYSTEM, so it took a bit of programmatic induction to determine the user account and profile of the user currently logging in, since the API's Microsoft provides for determining the logged-in user assume that the calls are coming from the user account in question. Therefore, they report back that SYSTEM is logged in. The service watches login and logout events in order to match up when a specific user has logged off and should have their profile deleted. It then removes the registry entries associated with that user outside of HKLM, and waits until the lock on the user's NTUSER.dat is free before deleting the profile folder.
"We skipped past Windows 8/8.1 for various reasons only to find that our service was no longer deleting profiles on logout, despite the service running, in Windows 10. An examination of the logs generated by the service showed us that the service was trying to delete the profile, but newly added files were staying locked well after users logged out and the service was giving up. Because we did not want to risk the profile deletion process blocking subsequent logins, we did not feel we could simply have the service wait and continue trying to delete profiles indefinitely until the locks were released.
"Our solution was to add threads to the service. Now, when a logoff event occurs the service spawns a thread to delete their profile. When a person logs in the service dispatches its own internal event to any child threads that may be running telling them the login name of the user who just logged in. The child threads compare the user name they are sent with the user name of the profile they are trying to delete, and if the names match, the child thread terminates because we really do not want some part of an active profile to get deleted while it is in use. If the child thread does not get interrupted, it will continue to try and delete the profile for up to 10 minutes. The service simply sleeps for 10 seconds after it catches a file locked failure then tries again until it either no longer runs into locked files and removes the profile or the 10 minutes runs out. We have found that it can take up to five minutes for a profile to be deleted in Windows 10 on a modern computer with a Skylake processor and a fast NVMe SSD drive.
"We needed to add some significant complexity to the service we wrote in order to accommodate the idiosyncrasies of Windows 10. However, a side effect has been that the service is actually more reliable and consistent at deleting profiles than ever before. About the only time we see profiles sticking around that otherwise should not be persistent is if there is a power event that shuts the computer off without a person actually logging off. Clearly, the service cannot delete the profile if there is no logoff event. Overall, we are quite happy with the results our service provides and it comes in at a lightweight 23KB."
Mark has generously made available to us the source code for the custom solution he has described here in this second part of our two-part article so that any readers who are interested in trying to implement it can test and/or customize his solution. These source code files are available for download as a zipped file here.
Mark also sent us the following note concerning these additional files:
I have attached a zipped version of the service that includes a little installation CMD file as well as some documentation on how to use it in Word and plain text. I have not updated the documentation since 2011, but it should still be accurate since the changes last year did not change the interface. I also included the C# source code as an attachment with the Visual Studio configuration file for the project. The rest of the files a project uses should be essentially created automatically by Visual Studio if anyone wants to re-create my work.
Please note that these downloadable files are presented "as is" with no warranty and no offer to provide any support, so please use and customize them at your own risk.