How could I determine which SMB client/session has a specific file open on a Server 2008R2 Windows file server?

9,402

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.

enter image description here

Share:
9,402

Related videos on Youtube

Rasmir
Author by

Rasmir

Updated on September 18, 2022

Comments

  • Rasmir
    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 and NET 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
    Rasmir over 11 years
    "Manage Open Files" provides the same information as NET FILE and "Manage Sessions" provides the same information as NET 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, but handles.exe shows System as having the files open.
  • Ryan Ries
    Ryan Ries over 11 years
    Ok 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
    Rasmir over 11 years
    Process Explorer also shows System as the responsible process, owned by NT AUTHORITY\SYSTEM.
  • Rasmir
    Rasmir over 11 years
    Ah, "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 and NET 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
    mfinni over 11 years
    One of many reasons to not share a user ID amongst people.
  • Ryan Ries
    Ryan Ries over 11 years
    @Rasmir Oh! Just run mmc. Add "Shared Folders" snapin. Look at Open Files. Close at will.
  • Rasmir
    Rasmir over 11 years
    While 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
    sean_m about 7 years
    This 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.