For those of you who already got the punchline, you can probably skip right down to the juicy bits which contain our solution for loops etc.
For those who have come across this because something else was getting you down which looks like this:
Or something else point to ‘Access Denied’ type errors and you don’t know what’s causing it, read on!
We wrote this article as a result of some challenges we were having with the Tanium agent. Whilst the agents are generally well behaved chaps, there is the occasional blip that we see where you might have to reinstall the client in order to get things back on track. We recently found one such scenario in troubleshooting some Threat Response errors which resulted in some pretty frustrating errors that we needed to get around. To put it in perspective though, these machines represented around 0.8% of the entire estate we upgraded from the original Detect, IR, Index, and Trace modules to Threat Response 2.1. More on that in another article.
So for those looking to Handle your file locks (still not got the pun yet?); we first need to understand what causes them. File locks are caused usually because another process is accessing a file and creates a reference to let other programs know that it has done so. These references are called ‘handles’ and are generally very useful for programmers to allocate and lock resources so that they doesn’t get mistaken for something available when the OS gets a request to provide resources for another app. In file terms, the handles provide a means of locking the file so that other processes can’t also write to the file and potentially cause corruption.
The challenge in any modern OS however is that there’s always loads going on in the background. AV is background scanning. The OS could be doing indexing. Applications will be writing their own files and referencing libraries. With all this activity; the chances of a file lock occurring on something you want to write to at some point is pretty high. And this would be fine, but if we REALLY need to disable the other processes from using that file, is there any way of identifying the file locks and removing them?
Enter the Sysinternals tool Handle by the legendary Mark Russinovich: https://docs.microsoft.com/en-us/sysinternals/downloads/handle
Handle is a command line tool which allows us to identify all of file handles in use across Windows, but also close specific handles if you really need to remove these file locks. Considering the amount of activity going on though, I’d highly recommend that you only use the handle -a command on your own machine just for fun as the quantity of data returned is staggeringly verbose and not particularly useful in its raw form. For us, we were writing our package to backup the Tanium Client files from a potentially broken client and then reinstall it so that an entirely new set of binaries are copied down, rather than a hopeful overwrite of the directory as used in the inbuilt Tanium packages. More on the mechanics of that in our other article, but suffice to say that despite stopping the services and terminating the processes, we still had file locks. First we need to work out which files are locking that directory which we can do with a simple handle “C:Program File (x86)TaniumTanium Client”. Run this and you should get something like the following output:
I know right? What a mission. But the need for Handle became clear to us when we were getting the file locks presented even after stopping the service. So we used handle again and even after service termination plus using a taskkill to terminate TaniumEndpointIndex.exe and TaniumReveal.exe, we still saw the following:
Now this list is smaller, but the command to end even the first handle would be handle -c 44 -y -p 8520. The next one would be handle -c 144 -y -p 8520 and so on until you’ve killed them all. Really.
You haven’t come here to retype the same command again and again though and we’re not going to disappoint! There is of course a better way and that way is by use of a for command (more on that here: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/for) which can allow us to create loops for several files or objects in a set. So say I wanted to do something clever like end every process that had a file lock against something in the Tanium Client files directory, I need to get for to grab the data from the third and sixth columns, store those in temporary variables and then run them against a handle command recursively. Want a spoiler? Oh go on then:
for /f “tokens=3,6 delims=: ” %A in (‘handle -accepteula “C:Program Files (x86)TaniumTanium Client”‘) DO handle -c %B -y -p %A
Because for is a little unrefined, you’ll get some weird results for the first few executions as it tries to grab the handle application preamble and run things like the year through it but what you will end up seeing after the first few is a series of successful executions which look like this:
Now go back and run that handle “C:Program File (x86)TaniumTanium Client” again and see how clean it looks:
Now go and rename that directory that you kept being told off was in use!
Oh and one last thing. We’ve made a neat package to wrap up this command if you need to kill file handles for a specific file or directory. Feel free to head over to our Downloads area and grab it and then over to https://docs.microsoft.com/en-us/sysinternals/downloads/handle for your handle executable to add to the package.