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

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


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

2 ответа

Решение

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


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

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

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

введите описание изображения здесь

Другие вопросы по тегам