How could I determine which SMB client/session has a specific file open on a Server 2008R2 Windows file server?
Solution 1
Much thanks to Ryan Ries for his patience and persistence.
What I've done is just a batch file which uses psexec (Sysinternals) to push handle.exe(also Sysinternals) to each client with an active SMB session as the target user and check for a handle matching the specified filename or partial filename.
This may not be very pretty, but functional is elegant and this seems to do the job. (That is, it gives me a list of IP addresses corresponding to a list of people I should be on the phone with.) It takes 15~20 seconds to run now, or ~30 if I take out filtering based on username.
The only argument should be the filename or filename fragment to match, although it could also be invoked with a target machine and a filename to check only that machine.
As NET SESSION
is used to get the session list, this must be run with administrator privileges by default. PsExec's documentation claims that PsExec will not return it's own status, so I suspect that false positives are possible if PsExec is unable to connect. It is also possible that the matching handle's file isn't on the share or is a different file, resulting in a false positive.
@SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
@ECHO OFF
IF "%2" NEQ "" GOTO :check
IF "%1" EQU "" ECHO No argument provided & GOTO :EOF
ECHO Waiting for all instances of psexec.exe to return...
FOR /F %%i in ('NET SESSION ^| findstr /I username') DO (
IF /I "%%i" NEQ "!LASTLINE!" (
start /B cmd /c %0 %%i %1
)
set LASTLINE=%%i
)
:WAIT
TIMEOUT 1 > NUL
TASKLIST | findstr /I psexec 2> NUL > NUL
IF %ERRORLEVEL% EQU 0 GOTO WAIT
ECHO Press any key to continue...
pause > NUL 2> NUL
EXIT /B
:check
PSEXEC.EXE -s %1 -c handle.exe /accepteula -a %2 2> NUL |findstr /I %2 > NUL 2> NUL
IF %ERRORLEVEL% EQU 0 ECHO Handle found on machine: %1
EXIT
Solution 2
You can usually get a pretty good idea of this just by opening "Share and Storage Management" on your 2008R2 server, and over in the right pane you'll see "Manage Sessions" and "Manage Open Files". You might try that first.
If that fails, you might try Process Explorer from Sysinternals. Do a handle search for the file name. The process that has an open handle to that file should be found. To what user account does that process belong?
EDIT: Sorry OP, I took you on a detour because I didn't fully understand your question.
Related videos on Youtube
Rasmir
Updated on September 18, 2022Comments
-
Rasmir almost 2 years
What I need is a way to associate a client name or IP address with an open file, so that I can cleanly close the file for maintenance.
NET SESSION
doesn't show the names of open files andNET FILE
doesn't show the client which has the file open. I had hoped that I could cross-reference the data from these two commands, but that doesn't seem possible. Everything else I've see provides the same data as these commands, with no apparent way to determine which client machine has the file open.
Clarification: I do not want to force the files closed on the server, risking file corruption and causing the client program to crash.
-
Rasmir over 11 years"Manage Open Files" provides the same information as
NET FILE
and "Manage Sessions" provides the same information asNET SESSION
. I would normally use the username to determine which client has the file open; as multiple clients are using a common username, that is not an option in this case. Process Explorer requires a reboot, buthandles.exe
shows System as having the files open. -
Ryan Ries over 11 yearsOk then go with option 2 and trace it back to the logon session. Process Explorer handle search for the file, find the process, the properties of that process will also contain the Logon Session to which it belongs.
-
Rasmir over 11 yearsProcess Explorer also shows System as the responsible process, owned by
NT AUTHORITY\SYSTEM
. -
Rasmir over 11 yearsAh, "session" in the title was a bit ambiguous. I'm talking about SMB sessions, dealing with files opened remotely. Also, you're right about Process Explorer; I was thinking of Nir Sofer's OpenedFilesView, which had come up as a potential
lsof
substitute. The files are held by a non-system process on the client machine andNET SESSION /DELETE
will end the session and release the file. I'm looking for a way to get which machine has the program running so that it can be closed cleanly. Sorry for the misunderstanding, but I appreciate the effort. -
mfinni over 11 yearsOne of many reasons to not share a user ID amongst people.
-
Ryan Ries over 11 years@Rasmir Oh! Just run mmc. Add "Shared Folders" snapin. Look at Open Files. Close at will.
-
Rasmir over 11 yearsWhile I agree, mfinni, I don't have final say on this one. --- Ryan, I'm aware of the ability to close files, but am concerned about potential corruption; hence the desire to find the machine and close the file gracefully. I think I have something hacked up for it, but suspect that it's not 100%.
-
sean_m about 7 yearsThis doesn't scale well across many file servers and users, my org has ~115 file servers and 20k users. I've turned to a combination of openfiles.exe constantly running against all the servers and some C++ that ingests it all but it seems like enabling audit logging on the shared directories and aggregating those into something searchable would be the best option for larger scale settings.