Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 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|improve this answer
    
"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. –  Rasmir Dec 19 '12 at 19:25
    
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. –  Ryan Ries Dec 19 '12 at 19:32
    
Process Explorer also shows System as the responsible process, owned by NT AUTHORITY\SYSTEM. –  Rasmir Dec 19 '12 at 19:39
    
I've never seen Process Explorer require a reboot. Maybe it won't start for the first time if your system is in a state of "reboot pending," like after patches or installs or something. Anyway, if System has your file held open, it'll probably never give it back until you reboot. (And if you close the handle you will probably crash.) Sorry. I thought we were talking about a person's user account holding the file open. :\ –  Ryan Ries Dec 19 '12 at 19:41
    
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. –  Rasmir Dec 19 '12 at 19:50
up vote 0 down vote accepted

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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.