Como eu poderia determinar qual cliente / sessão SMB tem um arquivo específico aberto em um servidor de arquivos do Windows Server 2008R2?

6

O que eu preciso é uma maneira de associar um nome de cliente ou endereço IP a um arquivo aberto, para que eu possa fechar o arquivo para manutenção. NET SESSION não mostra os nomes dos arquivos abertos e NET FILE não mostra o cliente que possui o arquivo aberto. Eu esperava poder cruzar a referência dos dados desses dois comandos, mas isso não parece possível. Tudo o mais que vejo fornece os mesmos dados que esses comandos, sem nenhuma maneira aparente de determinar qual máquina cliente tem o arquivo aberto.

Esclarecimento: Eu não quero forçar os arquivos a serem fechados no servidor, arriscando a corrupção do arquivo e fazendo com que o programa cliente falhe.

    
por Rasmir 19.12.2012 / 20:09

2 respostas

0

Muito obrigado a Ryan Ries por sua paciência e persistência.

O que eu fiz é apenas um arquivo em lote que usa psexec (Sysinternals) para enviar handle.exe (também Sysinternals) para cada cliente com uma sessão SMB ativa como o usuário de destino e verificar se há um identificador correspondente ao nome de arquivo especificado ou nome de arquivo parcial.

Isso pode não ser muito bonito, mas funcional é elegante e isso parece fazer o trabalho. (Ou seja, ele me fornece uma lista de endereços IP correspondentes a uma lista de pessoas com as quais eu deveria estar ao telefone.) Demora 15 ~ 20 segundos para ser executado agora, ou ~ 30 se eu remover a filtragem com base no nome de usuário.

O único argumento deve ser o nome do arquivo ou o fragmento de nome de arquivo para corresponder, embora também possa ser chamado com uma máquina de destino e um nome de arquivo para verificar apenas essa máquina.
Como NET SESSION é usado para obter a lista de sessões, isso deve ser executado com privilégios de administrador por padrão. A documentação do PsExec alega que o PsExec não retornará seu próprio status, então eu suspeito que falsos positivos sejam possíveis se o PsExec não conseguir se conectar. Também é possível que o arquivo do manipulador correspondente não esteja no compartilhamento ou seja um arquivo diferente, resultando em um falso positivo.

@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
    
por 03.01.2013 / 17:46
6

Normalmente você pode ter uma boa idéia disso apenas abrindo o "Gerenciamento de Compartilhamento e Armazenamento" no seu servidor 2008R2, e no painel direito você verá "Gerenciar Sessões" e "Gerenciar Arquivos Abertos". Você pode tentar isso primeiro.

Se isso falhar, você pode tentar o Process Explorer da Sysinternals. Faça uma pesquisa de identificador para o nome do arquivo. O processo que possui um identificador aberto para esse arquivo deve ser encontrado. Para qual conta de usuário esse processo pertence?

EDIT: Desculpe OP, eu levei você em um desvio porque eu não entendi completamente sua pergunta.

    
por 19.12.2012 / 20:15