web-dev-qa-db-ja.com

SMBクライアント/セッションが特定のファイルをサーバー2008R2 Windowsファイルサーバーで開いているかどうかをどのように判断できますか?

必要なのは、クライアント名またはIPアドレスを開いているファイルに関連付けて、メンテナンスのためにファイルを完全に閉じることができるようにする方法です。 NET SESSIONは開いているファイルの名前を表示せず、NET FILEは、ファイルを開いているクライアントを表示しません。これら2つのコマンドからのデータを相互参照できることを期待していましたが、それは不可能のようです。私が見た他のすべてのものは、これらのコマンドと同じデータを提供しますが、ファイルを開いているクライアントマシンを特定する明確な方法はありません。


説明:サーバー上でファイルを強制的に閉じたくないので、ファイルが破損してクライアントプログラムがクラッシュするおそれがあります。

6
Rasmir

ライアン・リースの忍耐と粘り強さに感謝します。


私がやったことは、psexec(Sysinternals)を使用して、アクティブなSMBセッションを持つ各クライアントにhandle.exe(またSysinternals)をプッシュし、ターゲットユーザーとして確認するバッチファイルです。指定されたファイル名または部分的なファイル名に一致するハンドル。

これは非常にきれいではないかもしれませんが、機能はエレガントであり、これは仕事をするようです。 (つまり、電話をかけるべき人のリストに対応する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
0
Rasmir

通常は、2008R2サーバーで[共有とストレージの管理]を開くだけでかなり良いアイデアが得られます。右側のペインに[セッションの管理]と[開いているファイルの管理]が表示されます。最初に試してみてください。

それが失敗した場合は、SysinternalsのProcess Explorerを試してみてください。ファイル名をハンドル検索します。そのファイルへのオープンハンドルを持つプロセスが見つかります。そのプロセスはどのユーザーアカウントに属していますか?

編集:申し訳ありませんがOP、私はあなたの質問を完全に理解していなかったので、回り道に連れて行きました。

enter image description here

6
Ryan Ries