我需要一种将客户端名称或 IP 地址与打开的文件关联起来的方法,这样我就可以干净利落地关闭文件进行维护。NET SESSION
不显示打开文件的名称,也不NET FILE
显示打开文件的客户端。我曾希望可以交叉引用这两个命令的数据,但这似乎不可能。我看到的其他所有内容都提供与这些命令相同的数据,没有明显的方法来确定哪台客户端计算机打开了文件。
澄清:我不想强制关闭服务器上的文件,因为这会造成文件损坏并导致客户端程序崩溃。
答案1
通常,您只需在 2008R2 服务器上打开“共享和存储管理”,然后在右侧窗格中看到“管理会话”和“管理打开文件”即可对此有一个很好的了解。您可以先尝试一下。
如果失败,您可以尝试使用 Sysinternals 中的 Process Explorer。对文件名进行句柄搜索。应该可以找到具有该文件的打开句柄的进程。该进程属于哪个用户帐户?
编辑:抱歉,楼主,我带你绕了个弯,因为我没有完全理解你的问题。
答案2
非常感谢 Ryan Ries 的耐心和坚持。
我所做的只是一个批处理文件,它使用 psexec(Sysinternals)将 handle.exe(也是 Sysinternals)推送到每个具有活动 SMB 会话作为目标用户的客户端,并检查与指定文件名或部分文件名匹配的句柄。
这可能不是很漂亮,但功能很优雅,而且似乎能完成工作。(也就是说,它为我提供了一个 IP 地址列表,这些 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