How to use the SysInternals Handle Tool to Tracked Down Locked Files

Adam Bertram

Read more posts by this author.

Sysinternal’s handle.exe is a third-party tool that can help track down a process that is locking down a file you are trying to access. In this article, you’re going to learn how to download the handle utility and even build a small PowerShell script to automate the process of finding locked files!

The best way to track down processes that have your files open is the third party utility handle.exe. Part of the popular SysInternals tool set, handle.exe looks at the file system and attempts to find all open file handles.

As part of its output, it also returns the process. We can use some PowerShell to wrap some code around this utility to provide an easy way to provide handle.exe with a particular file path and then be presented with a process.

Downloading Handle

First of all, you’ll need to download and unzip handle. This can either be done manually, or if you’re a PowerShell geek like me, you can do it via PowerShell.

Invoke-WebRequest -Uri 'https://download.sysinternals.com/files/Handle.zip' -OutFile C:\handle.zip
PS> Expand-Archive -Path C:\handle.zip

Running Handle

Once downloaded, let’s now just run handle and see what the output looks like. You can see that the output is pretty ugly and there’s no way to limit it down by a file name.

Running the SysInternals handle utility
Running the SysInternals handle utility

With the standard output alone, it will be a pain to track down a locked file. To fix that, you can create a little PowerShell function to parse the output and find only the line you’re interested in.

function Find-LockedFileProcess {
     param(
         [Parameter(Mandatory)]
         [string]$FileName,
 
         [Parameter()]
         [string]$HandleFilePath = 'C:\Handle\handle.exe'
     )
 
     $splitter = '------------------------------------------------------------------------------'
     $handleProcess = ((& $HandleFilePath) -join "`n") -split $splitter | Where-Object {$_ -match [regex]::Escape($FileName) }
     (($handleProcess -split "`n")[2] -split ' ')[0]
 }

This small PowerShell function is doing a lot of text parsing. Unfortunately, the Sysinternals handle.exe is a command-line utility. When it was created, it had no idea what PowerShell was so going in line with other utilities of the time just dumped a bunch of text to the console.

As you can see, we can make it more user-friendly, but it requires some ugly string parsing like using the split operator, the new line character (`n) and some regular expressions. Regardless, it only has to be done once, and I’ve already done it for you!

Let’s now copy and paste this function into a PowerShell console and give it a spin. I’ve opened up a Microsoft Word document called TestWordDoc.docx. I know that Word does lock the file when open. Let’s see if our function can find what process is locking that file.

PS> Find-LockedFileProcess -FileName TestWordDoc.docx
WINWORD.EXE

Success! You can see now instead of seeing all of that output at once; we can provide a single file name and get back a single process. This is exactly what we’re after.

Looks like you're offline!