.png)
弊社の社員が週末でも 24 時間 365 日コンピューターを起動したままにしておくという問題があります。弊社の企業ポリシーでは、使用していないときはシャットダウンすることになっていますが、いつもそうできるわけではありません。そこで、PsInfo を使用してコンピューターの稼働時間を取得する簡単なスクリプトを実行しています。AD からコンピューターのリストをテキスト ファイルにエクスポートし、バッチ ファイルを使用してリストを調べ、稼働時間情報を引き出し、別のテキスト ファイルに保存します。
For /F "tokens=*" %%i in (ComputerList.txt) do psinfo uptime -nobanner \\%%i 1>>UptimeResults.txt
うまく動作しますが、コンピューターがオンラインでない場合、デフォルトのタイムアウトは 60 秒のようで、数百台のコンピューターでスクリプトの実行に非常に長い時間がかかる可能性があります。PsExec 自体には使用できるタイムアウト スイッチがありますが、PsInfo はこれを考慮していないようです。10 秒後に強制的にタイムアウトさせる方法や、同じことを実行する別のプログラムはありますか? タイムアウト スイッチと他のコマンドを使用して PsExec を直接使用する方法は? ちなみに、すでに fastboot を無効にしているので、アップタイムの結果は正確です。
私たちが議論してきたが、より簡単な解決策を期待していることは、PsExec を使用して実行し、systeminfo | find "Boot Time"
起動時間を分析し、計算を行って実行時間を取得することです。uptime.exe の古いコピーを取得してコンピューターに展開し、その出力を PsExec で使用します。そして、最後の起動時間を WMI でポーリングして再度計算する PowerShell コマンドに切り替えます。すべて過度に複雑に思えるので、誰かがより良い提案をしない限り、簡単だが時間のかかる解決策の方が良いと思います。
答え1
好きグレッグの提案最後の起動時間を取得します。
しかし、次の方法で、ご要望どおりの結果が得られると確信しています。WMIC を使用して、新しい cmd.exe セッション内で PSINFO を起動します。FOR /F は、新しい CMD セッションの PID をキャプチャするために使用されます。次に、最大 10 秒間プロセスを監視するルーチンを呼び出します。プロセスが実行されていない場合は、すぐに戻ります。ただし、10 秒後には、戻る前にプロセスを強制終了します。
ダミーの TIMEOUT プロセスを使用して起動および監視プロセスをテストしました。ただし、PSINFO も環境も持っていないため、PSINFO を使用してテストすることはできませんでした。
@echo off
setlocal
set "timeout=10"
set "log=UptimeResults.txt"
:: Start with an empty result file
copy /y nul %log% >nul
:: Loop through the list of computers
for /f "tokens=*" %%i in (ComputerList.txt) do (
%= For each computer, launch PSINFO via wmic and use FOR /F to capture the parent cmd.exe session PID =%
%= The cd argument is the location where the process should run (current directory) =%
for /f "tokens=2 delims=;= " %%P in (
'wmic process call create 'cmd /c "psinfo uptime -nobanner \\%%i 1>>%log%"'^, "%cd%" ^| find "ProcessId"'
) do call :monitor %%P 2>nul 1>nul
)
exit /b
:monitor PID
:: Monitor up to %timeout% seconds and return immediately if process no longer running
for /l %%N in (1 1 %timeout%) do (
timeout 1
tasklist /fi "pid eq %1" | find "cmd.exe" || exit /b
)
:: It has been longer than %timeout% seconds, so kill the process
taskkill /pid %1 /f /t
exit /b