Windows-Server-2008-R2

如何確定哪個 SMB 客戶端/會話在 Server 2008R2 Windows 文件伺服器上打開了特定文件?

  • January 16, 2013

我需要一種將客戶端名稱或 IP 地址與打開的文件相關聯的方法,以便我可以乾淨地關閉文件以進行維護。NET SESSION不顯示打開文件的名稱,也不顯示打開文件NET FILE的客戶端。我曾希望我可以交叉引用這兩個命令中的數據,但這似乎是不可能的。我看到的所有其他內容都提供了與這些命令相同的數據,沒有明顯的方法來確定哪個客戶端機器打開了文件。


**澄清:**我不想強制關閉伺服器上的文件,以免文件損壞並導致客戶端程序崩潰。

非常感謝 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

您通常可以通過在 2008R2 伺服器上打開“共享和儲存管理”來了解這一點,然後在右側窗格中您將看到“管理會話”和“管理打開的文件”。你可以先試試。

如果失敗,您可以嘗試 Sysinternals 的 Process Explorer。對文件名進行句柄搜尋。應該找到對該文件具有打開句柄的程序。該程序屬於哪個使用者帳戶?

編輯:對不起,OP,我帶你走了彎路,因為我沒有完全理解你的問題。

在此處輸入圖像描述

引用自:https://serverfault.com/questions/459426