Open file handles are a common feature of PowerShell. They allow you to access files from any location on your computer. You can use these handles to manage files and folders, as well as to create and delete files. To manage open file handles with PowerShell, you first need to create a new object called OpenFileHandle. This object will contain the information necessary to manage open file handles. Next, you need to set the properties of the OpenFileHandle object. These properties will include the handle name, the path to the file or folder that you want to access, and whether or not you want to allow other users to access the handle. Finally, you need to call the OpenFileHandle object’s New() method. This method will create an open file handle for you and return it back into your OpenFileHandle object. You can then use this handle in various PowerShell commands related to managing files and folders.
Microsoft introduced PowerShell as a replacement shell, but it has far more functionality than that and is a complex and capable language. Let’s look in this article on how you can utilize PowerShell to deal with locked files.
The Locked File Problem
How exactly does a file get locked? During normal use, a process creates many handles to resources such as a file. By doing so, the processes often lock the file to prevent unintended configuration changes or other corruption from taking place. The problem often is that it is difficult to determine what process has locked the file, and subsequently, how to remove that lock from the file.
Unfortunately, there is no built-in cmdlet to test a file and tell whether it is locked or by what process. Therefore, you need to create your own functions or wrap other useful tools that exist to assist in finding out more about these files.
Testing for Locked Files
Within Windows, you are able to test to see if an individual file is locked. Using the following code block, you can test to see if a given file is locked. The $Item variable needs to be set to a full file path. By testing to see if the file can be opened for writing, as seen with the [System.IO.File]::Open($Item,‘Open’,‘Write’) command, you can tell if the file is locked.
Get-SMBOpenFile
I did say that Windows doesn’t have a built-in function, but there is one case where a function does exist. If you have a remote share or even administrative shares (such as c$), then you can use the Get-SMBOpenFile cmdlet to report on those open files.
The downside is that this only works for files that are remotely accessed. Any locked files that are in use on your local system won’t be reported on, so for most cases this is not a viable solution. To close, you can pipe the open files returned to the Close-SMBOpenFile command.
Get-SMBOpenFile | Close-SMBOpenFile
OpenFiles Utility
Windows has a built-in utility named openfiles that can help list what files are in use and disconnect them. At first glance, it looks perfect for your needs! You can even wrap this within a PowerShell function to ease the querying and disconnecting of files.
Open up an Administrative PowerShell prompt and run the command openfiles /query. Right away, you should receive an error message stating that the “maintain objects list” global flag needs to be on.
This objects list is what actually maintains the list of handles that are in use and enables openfiles to query that information. To turn this on, enter in openfiles /local on and then restart your computer. The downside to turning this feature on is that there is a slight performance hit, which depending on your system, may not be worth the utility of using this tool. That being said, let’s see how we can make this work within PowerShell.
With the previous examples, you can see how to import the CSV output of openfiles into PowerShell. Using that information, you can then disconnect a file to unlock it. Due to the performance hit you may incur with enabling the maintain objects list capability, it might not be worthwhile for your needs. Because of that, other solutions may be needed.
The Handle Application
Sysinternals is known for the many useful and nearly essential IT tools that they make. Some time ago, Sysinternals was acquired by Microsoft, and you can download and use these well-supported tools for yourself. Conveniently, there is an application named handles that provides exactly what you are looking for!
First, youneed to download the application, unzip the files, and put the executables in a location that your Path environmental variable has included. By doing so, you can easily reference the application wherever you need it. Using a simple query for open files, you can see that you get a lot of results (truncated for readability).
You seem to get what you want—at least a way to find out what files are being used—and you can test them using your file locked code from before. But how do you make this easier to use? The following code reads each process and retrieves just the locked files. The downside is that this takes a while to run as there are many processes.
Ultimately though, what you get is an actionable collection of files, listed by process, that you know are in use and can be further filtered. If you find out that you need to close one of them, you can do the following (as an Administrator):
You can further wrap all of this in a function to make it even easier to parse and search as necessary. TMany possibilities exist, especially in combining the various methods into a solution that fits your environment.
Conclusion
Dealing with locked files can be a challenge, especially when it stops what you need to get done quickly. There are a number of ways to find and unlock those files, but it does require a bit of work as Windows does not have a truly comprehensive built-in method of dealing with those locked files. The solutions outlined should make short work of whatever the issue might be and let you move on to far more important tasks!