Usando PsInfo com um procedimento de tempo limite (ou canalizando através do PsExec?)

Usando PsInfo com um procedimento de tempo limite (ou canalizando através do PsExec?)

Temos um problema com pessoas em nossa empresa que deixam seus computadores funcionando 24 horas por dia, 7 dias por semana, mesmo nos finais de semana. Nossa política corporativa é desligar quando não estiver em uso, mas isso nem sempre acontece. Então, o que temos feito é executar um script simples usando PsInfo para reduzir o tempo de atividade dos computadores. Exportamos a lista de computadores do AD para um arquivo de texto e usamos um arquivo em lote para percorrer a lista, extrair as informações de tempo de atividade e salvá-las em outro arquivo de texto:

For /F "tokens=*" %%i in (ComputerList.txt) do psinfo uptime -nobanner \\%%i  1>>UptimeResults.txt

Funciona muito bem, mas se um computador não estiver online, o tempo limite padrão parece ser de 60 segundos, o que pode fazer com que o script demore muito para centenas de computadores. O próprio PsExec possui um botão de tempo limite que você pode usar, mas o PsInfo não parece levar isso em consideração. Existe outra maneira de forçar o tempo limite após, digamos, 10 segundos ou um programa diferente que fará a mesma coisa? Possivelmente usando o PsExec diretamente com a opção de tempo limite e algum outro comando? Como observação, já desativamos o fastboot para que os resultados do tempo de atividade sejam precisos.

Coisas que discutimos, mas esperamos uma solução mais fácil: usar o PsExec e executar, systeminfo | find "Boot Time"analisar o tempo de inicialização e fazer algumas contas para obter o tempo de execução. Obtendo uma cópia antiga do uptime.exe, implantando-a nos computadores e usando sua saída com o PsExec. E mudando para um comando do PowerShell que pesquisaria o WMI pela última inicialização e faria as contas novamente. Todos parecem excessivamente complicados e preferem uma solução fácil, mas lenta, a menos que alguém tenha uma sugestão melhor.

Responder1

Eu gostoSugestão de Gregpara obter o último horário de inicialização.

Mas acredito que o seguinte fará o que você pediu. Eu uso o WMIC para iniciar o PSINFO em uma nova sessão cmd.exe. FOR /F é usado para capturar o PID da nova sessão CMD. Depois chamo uma rotina para monitorar o processo por até 10 segundos. Se não estiver mais em execução, retorne imediatamente. Mas depois de 10 segundos eu mato o processo antes de retornar.

Testei o processo de inicialização e monitoramento com um processo TIMEOUT fictício. Mas não consegui testar com PSINFO porque não tenho PSINFO, nem tenho o seu ambiente.

@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

informação relacionada