如何确定哪个 SMB 客户端/会话在 Server 2008R2 Windows 文件服务器上打开了特定文件?

Ras*_*mir 6 network-share server-message-block windows-server-2008-r2

我需要的是一种将客户端名称或 IP 地址与打开的文件相关联的方法,以便我可以干净地关闭文件以进行维护。NET SESSION不显示打开文件的名称,也不显示打开文件NET FILE的客户端。我曾希望我可以交叉引用来自这两个命令的数据,但这似乎不可能。我看到的其他所有内容都提供与这些命令相同的数据,但没有明显的方法来确定哪个客户端机器打开了文件。


澄清:我不想强制关闭服务器上的文件,冒着文件损坏的风险并导致客户端程序崩溃。

Rya*_*ies 6

您通常可以通过在 2008R2 服务器上打开“共享和存储管理”来对此有一个很好的了解,然后在右窗格中您将看到“管理会话”和“管理打开的文件”。你可以先试试。

如果失败,您可以尝试使用 Sysinternals 的 Process Explorer。对文件名进行句柄搜索。应该找到具有该文件的打开句柄的进程。该进程属于哪个用户帐户?

编辑:对不起,OP,我带你绕道而行,因为我没有完全理解你的问题。

在此处输入图片说明


Ras*_*mir 0

非常感谢 Ryan Ries 的耐心和坚持。


我所做的只是一个批处理文件,它使用 psexec (Sysinternals) 将 handle.exe(也是 Sysinternals)推送到每个具有活动 SMB 会话的客户端作为目标用户,并检查是否有与指定文件名或部分文件名匹配的句柄。

这可能不是很漂亮,但功能很优雅,而且这似乎可以完成工作。(也就是说,它为我提供了与我应该通话的人员列表相对应的 IP 地址列表。)现在运行需要 15~20 秒,如果我根据用户名进行过滤,则需要大约 30 秒。

唯一的参数应该是要匹配的文件名或文件名片段,尽管也可以使用目标计算机和文件名来调用它以仅检查该计算机。
由于NET SESSION用于获取会话列表,默认情况下必须以管理员权限运行。PsExec 的文档声称 PsExec 不会返回它自己的状态,因此我怀疑如果 PsExec 无法连接,则可能会出现误报。匹配句柄的文件也可能不在共享上或者是不同的文件,从而导致误报。

@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
Run Code Online (Sandbox Code Playgroud)