In my workplace, our helpdesk has a need for the ability to quickly and easily delete user profiles remotely. I did a little tinkering with wbemtest and found I could call the Delete() method on any of the WMI objects returned by the query “SELECT * FROM Win32_UserProfile.” It will properly delete the profile’s associated files and registry keys the same way that the windows native GUI tools do it. The problem with the native tool however, is that you need to be logged in to use it. It is fairly slow and clunky, and you can only select one profile at a time for deletion. This accounts for a lot of wasted time. So I took what I learned and created a little vbs script that made some WMI calls and deleted profiles. This worked great, but the help desk needs the ability to selectively choose which profiles get deleted through some form of user interface. I wanted the simplest possible solution that required no dependencies. (.NET, AutoIT DLL’s, etc). I found the best way to do that was to make an HTA application.
The first version of my profile cleanup HTA was very basic but served its purpose well. The problem was everything was done using synchronous WMI calls. I’ve recently been playing with a lot of Node.js to understand this whole “non-blocking IO” asynchronous programming methodology, and it got me wondering if I could do the same with this HTA application. It’s not difficult to find examples online for creating WMI queries and calling methods asynchronously, but getting them to play nice in the HTA application proved to be a challenge. At least for me : ).
One problem I had was certain things only worked using jScript, while other things only worked using VBscript. Fortunately I found a way to use both and reference functions in both languages from either language. The next problem I had was finding a way to reference the “WbemScripting.SWbemSink” object within HTA. The way I found to do it was by referencing the object by its class ID like so:
<object id="oSink" classid="clsid:75718C9A-F029-11D1-A1AC-00C04FB6C223"></object>
My first attempts at improving the UI was to make the function calls using the setTimeout javascript function but that didn’t seem to change anything. To prevent the windows from freezing I had to do everything asynchronously within WMI. I’m including links to both versions of the application. The old version should really only be used for educational purposes for developers interested in a before and after demonstration of asynchronous WMI vs standard synchronous WMI. The second version works quite well and is safe to use in production. Just be sure you don’t accidentally delete some important data in a user’s profile. Any comments, suggestions, improvements or questions are welcome!
Thank you so much for the script.
Is there anyway you can rename a profile folder instead of deleting it? Just want to know if it is possible to rename a folder with today’s date in case I need to restore any files. Thanks
I don’t think that is possible using the “Delete” WMI method I’m calling on the Win32_UserProfile object, but it would probably work if you added a little code to change the name before the delete method was called. The only potential issue I can think of is WMI complaining about the path missing after you’ve renamed it. It might need to be renamed, then create a directory in the same place with the original name, then call the delete method so it can delete what it is expecting to delete.
Great tool 🙂
I’m trying to delete some old profiles on a remote computer. I’ve tried delprof2 and it doesn’t delete them because it says they are in use. maybe I’m running into the same problem with your tool. I choose the computer and the profiles show up. I choose the ones I want to delete and click on the Delete button. The profiles are not deleted. The ones I’ve selected in your tool turns red and a number shows up in parentheses. The number is -2147024809. Not sure what the number is?
Could be locked files in the profile. Maybe reboot the PC and try again.
I run your script on Win10 and get “access is denied” pop-up. Any ideas? It works flawlessly on Win 7. From Win 7, I can delete profiles on Win 7 or Win 10 computers. From Win 10, it only works against the computer I run it on. It doesn’t work on any other computers on network. Check wbemtest and I can connect to \\xxxx\root\cimv2 without any error.
You can try the latest build from my GitHub repository. https://github.com/lspiehler/Remote_Profile_Remover I am using it in a Microsoft Active Directory environment on Windows 10 and Windows 7 interchangeably. Also works on every Server OS I’ve tested with.
It works nicely on Win7 aganist Win7 and Win10 profiles but I get “access is denied” when I run it from a Win10. Any idea?
great code btw.
since i have not confirmed it on the remote machine. This does remove the user profile and the registry keys as well?
Also since I have to do many laptops and desktops, is it possible to include a “select all” option so I don’t have to click each of them one at a time?
I added a “Select All” option in my latest build just now on GitHub. https://github.com/lspiehler/Remote_Profile_Remover It will remove the user profile directory and all associated registry keys. This is done by calling a WMI method. It is the same method Windows uses natively, so it is a very “clean” way of removing profiles. Aka, no “temporary profile” issues afterward…
Much appreciated. I have looked a long time from something like this. Makes my IT job so much easier when I don’t have to visit each machine each time something goes “funky”. Thank you for all your hard work and fantastic program.
Your welcome. Thank you for your input!
Just the tool I was looking for, simple and it works. Thank you my sweet Lyas.