Назад | Перейти на главную страницу

Как я могу определить, в каком SMB-клиенте / сеансе открыт определенный файл на файловом сервере Windows Server 2008R2?

Мне нужен способ связать имя клиента или IP-адрес с открытым файлом, чтобы я мог аккуратно закрыть файл для обслуживания. NET SESSION не показывает имена открытых файлов и NET FILE не показывает клиента, у которого открыт файл. Я надеялся, что смогу сопоставить данные из этих двух команд, но это казалось невозможным. Все остальное, что я видел, предоставляет те же данные, что и эти команды, без очевидного способа определить, на какой клиентской машине открыт файл.


Уточнение: Я не хочу принудительно закрывать файлы на сервере, что может привести к повреждению файла и сбою клиентской программы.

Обычно вы можете получить довольно хорошее представление об этом, просто открыв «Управление общими ресурсами и хранилищем» на сервере 2008R2, и на правой панели вы увидите «Управление сеансами» и «Управление открытыми файлами». Вы можете попробовать это в первую очередь.

Если это не поможет, вы можете попробовать Process Explorer от Sysinternals. Выполните поиск дескриптора по имени файла. Необходимо найти процесс, у которого есть открытый дескриптор этого файла. Какой учетной записи пользователя принадлежит этот процесс?

РЕДАКТИРОВАТЬ: Извините, ОП, я взял вас в объезд, потому что я не полностью понял ваш вопрос.

Большое спасибо Райану Райсу за его терпение и настойчивость.


То, что я сделал, - это просто командный файл, который использует 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