.png)
Wir haben ein Problem damit, dass Leute in unserem Unternehmen ihre Computer rund um die Uhr laufen lassen, sogar am Wochenende. Unsere Unternehmensrichtlinie sieht vor, sie herunterzufahren, wenn sie nicht verwendet werden, aber das passiert nicht immer. Deshalb haben wir ein einfaches Skript mit PsInfo ausgeführt, um die Betriebszeit der Computer zu verkürzen. Wir exportieren die Liste der Computer aus AD in eine Textdatei, verwenden dann eine Batchdatei, um die Liste durchzugehen, die Betriebszeitinformationen abzurufen und sie in einer anderen Textdatei zu speichern:
For /F "tokens=*" %%i in (ComputerList.txt) do psinfo uptime -nobanner \\%%i 1>>UptimeResults.txt
Funktioniert prima, aber wenn ein Computer nicht online ist, scheint das Standard-Timeout 60 Sekunden zu betragen, was dazu führen kann, dass das Skript bei Hunderten von Computern sehr lange dauert. PsExec selbst hat einen Timeout-Schalter, den Sie verwenden können, aber PsInfo scheint dies nicht zu berücksichtigen. Gibt es eine andere Möglichkeit, ein Timeout nach beispielsweise 10 Sekunden zu erzwingen, oder ein anderes Programm, das dasselbe tut? Möglicherweise kann man PsExec direkt mit dem Timeout-Schalter und einem anderen Befehl verwenden? Nebenbei bemerkt haben wir Fastboot bereits deaktiviert, sodass die Betriebszeitergebnisse korrekt sind.
Dinge, die wir diskutiert haben, aber auf eine einfachere Lösung hoffen: PsExec verwenden und ausführen, systeminfo | find "Boot Time"
dann die Startzeit analysieren und einige Berechnungen durchführen, um die Laufzeit zu ermitteln. Eine alte Kopie von uptime.exe abrufen, sie auf den Computern bereitstellen und ihre Ausgabe mit PsExec verwenden. Und auf einen Powershell-Befehl umsteigen, der WMI nach der letzten Startzeit abfragt und die Berechnungen erneut durchführt. Alles scheint übermäßig kompliziert und ich würde lieber die einfache, aber langsame Lösung wählen, es sei denn, jemand anderes hat einen besseren Vorschlag.
Antwort1
Ich magGregs Vorschlagum die letzte Startzeit abzurufen.
Aber ich glaube, das Folgende wird das tun, wonach Sie gefragt haben. Ich verwende WMIC, um PSINFO innerhalb einer neuen cmd.exe-Sitzung zu starten. FOR /F wird verwendet, um die PID der neuen CMD-Sitzung zu erfassen. Dann rufe ich eine Routine auf, um den Prozess bis zu 10 Sekunden lang zu überwachen. Wenn er nicht mehr läuft, kehre ich sofort zurück. Aber nach 10 Sekunden beende ich den Prozess, bevor ich zurückkehre.
Ich habe den Start- und Überwachungsprozess mit einem Dummy-TIMEOUT-Prozess getestet. Ich konnte jedoch nicht mit PSINFO testen, da ich weder PSINFO noch Ihre Umgebung habe.
@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