These days I am migrating some data from our old network file server to a new network storage. The plan is to migrate one folder at the time, and I have found out that in such a situation it can be useful to know how to to close all the open files in a specific directory before migrating in order to evite open files conflicts.
As I do not want to migrate all the data at once (this would be pretty much unpractical with so many gigabytes of data), I cannot simply adopt the solutions of shutting down or restricting access on the fileshare for everyone.
PSFile.Exe from SysInternals is our best friend in this case. Using this small utility, it is possible to retrieve all the open files in a given remote directory and close them altogether.
This is the way it should be used:
This command will close all open network files which match the expression "t:\folder\subfolder" on the file server \\fileserver.yourcompany.com.
The output will look like this:
Closed file t:\folder\subfolder\testfile1.xlsx on fileserver.yourcompany.com.
Closed file t:\folder\subfolder\testfile2.docx on fileserver.yourcompany.com.
Please note that when you close file handles based on their path, it is important to know that if the path contains spaces, it must be enclosed in quotes, like I did ("t:\folder\subfolder").
Let's have a look at the details of this operation.
When running psfile \\fileserver.yourcompany.com "t:\folder\subfolder" -c PSFile does connect to the remote fileserver through its IP address and asks the remote System process (PID: 4) to enumerate the open handles on the BasePath t:\folder\subfolder. The used protocol is a poorly known Server Service Remote Protocol (SRVS), which is a remote procedure call (RPC)–based protocol that is used for remotely enabling file and printer sharing and named pipe access to the server through the MSRPC, SMB2, SMBOverTCP and finally TCP protocols.
The method used to enumerate the open handles is NetrFileEnum, which returns information about some or all open files on a server, depending on the switches used with PSFile.
The fileserver answers to NetrFileEnum with a NetrFileEnum Response indicating the number of entries (read: open files) found. In the SRVS network packet each open file is inserted in a Coni1UserName variable which contains the open file path and the corresponding owner (the person who actually remotely opened the file).
So, for each open entry, PSFile starts a new MSRPC binding to the SRVS Service and sends out a NetrFileClose Request indicating the FileId to close, to which the fileserver answers with a "ReturnValue: 0x00000000 - ERROR_SUCCESS - The operation completed successfully" message.
The SMB2 session is then closed, the files are unlocked and the migration can be accomplished without ever getting any "The process cannot access the file because it is being used by another process" error message.
Here's the complete syntax for PSFile for your reference:
PsFile lists or closes files opened remotely.
Usage: psfile [\\RemoteComputer [-u Username [-p Password]]] [[Id | path]
-u Specifies optional user name for login to remote computer.
-p Specifies password for user name.
Id Id of file to print information for or close.
Path Full or partial path of files to match.
-c Closes file identified by file Id.
Omitting a file identifier has PsFile list all files opened remotely.
We could have also locally used "net file ID /close" but that would require us to log on the fileserver and to manually enter the file ID, which would take a bit more work because the operation should be repeated for each file.
I hope you enjoyed this article. Do not hesitate to leave a comment if so!