Скрипт для удаленной перезагрузки компьютера с отслеживанием хода ее выполнения

Для удаленной перезагрузки компьютера с ОС Windows 2000+ можно воспользоваться утилитой shutdown.exe. Однако она не позволяет выполнять мониторинг хода перезагрузки. Обычно для этих целей я использую скрипт на PowerShell, так как он в процессе перезагрузки следит за прекращением и последующим возобновлением RPC ping, ICMP ping и в итоге выдает состояние служб после перезагрузки.

Результат работы скрипта выглядит следующим образом:

PS C:\Scripts> .\reboot.ps1 USER-PC
Started restart attempt on USER-PC at 16:34:25
Restart request was accepted by the server at 16:34:26
Waiting on RPC ping fail...
RPC Ping fail detected at 16:34:37
Waiting on ICMP Ping fail...
ICMP Ping fail detected at 16:34:57
Waiting on ping resume...
ICMP ping resumed at 16:35:46
RPC Ping resumed at 16:35:46
Waiting 180 seconds for service startup...
state name status
----- ---- ------
Running AcrSch2Svc OK
Running AeLookupSvc OK
Running AudioEndpointBuilder OK
Running Audiosrv OK
Running Automatic LiveUpdate Scheduler OK
Running BFE OK
Running BITS OK
Running BlueSoleilCS OK
Running Browser OK
Running BsMobileCS OK
Running ccEvtMgr OK
Running ccSetMgr OK
Running Client32 OK
Running CryptSvc OK
Running CscService OK
Running DcomLaunch OK
Running Dhcp OK
Running Dnscache OK
Running DPS OK
Running EMDMgmt OK
Running Eventlog OK
Running EventSystem OK
Running FDResPub OK
Running gpsvc OK
Running hidserv OK
Running IAANTMON OK
Running IISADMIN OK
Running IKEEXT OK
Running iphlpsvc OK
Running KtmRm OK
Running LanmanServer OK
Running LanmanWorkstation OK
Running lmhosts OK
Running MMCSS OK
Running MpsSvc OK
Running Net Driver HPZ12 OK
Running Netlogon OK
Running netprofm OK
Running NlaSvc OK
Running nsi OK
Running PcaSvc OK
Running PlugPlay OK
Running Pml Driver HPZ12 OK
Running PolicyAgent OK
Running ProfSvc OK
Running RemoteRegistry OK
Running RpcSs OK
Running SamSs OK
Running SCardSvr OK
Running Schedule OK
Running seclogon OK
Running SENS OK
Stopped SharedAccess OK
Running ShellHWDetection OK
Running slsvc OK
Running SmcService OK
Running Spooler OK
Running stisvc OK
Running Symantec AntiVirus OK
Running SysMain OK
Running TabletInputService OK
Stopped TBS OK
Running TermService OK
Running Themes OK
Running TrkWks OK
Running upnphost OK
Running UxSms OK
Running VMAuthdService OK
Running VMnetDHCP OK
Running vmount2 OK
Running VMware NAT Service OK
Running W32Time OK
Running WebClient OK
Running WerSvc OK
Stopped WinDefend OK
Running Winmgmt OK
Running Wlansvc OK
Running WPDBusEnum OK
Running wscsvc OK
Running WSearch OK
Running wuauserv OK
Running wudfsvc OK
Running XAudioService OK

В зависимости от вашей конфигурации, возможно понадобится изменить значения таймаутов  в переменных $pingfail_timeout, $pingresume_timeout, $servicecheck_delay. Имя компьютера, который необходимо перезагрузить, передается в качестве параметра.

Ниже приведен сам скрипт reboot.ps1:

#Monitored restart function
#mjolinor 05/16/2010
function monitored-restart {
param ($server = $(throw "A server name is required."))$events = @()
$events += "Started restart attempt on $server at $((get-date).tolongtimestring())`n"
Write-Host "Started restart attempt on $server at $((get-date).tolongtimestring())`n"$pingfail_timeout = 180
$pingresume_timeout = 180
$servicecheck_delay = 180function Test-Port{
Param([string]$srv,$port=135,$timeout=1000,[switch]$verbose)
$ErrorActionPreference = "SilentlyContinue"
$tcpclient = new-Object system.Net.Sockets.TcpClient
$iar = $tcpclient.BeginConnect($srv,$port,$null,$null)
$wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
if(!$wait)
{
$tcpclient.Close()
if($verbose){Write-Host "Connection Timeout"}
Return $false
}
else
{
$error.Clear()
$tcpclient.EndConnect($iar) | out-Null
if($error[0]){if($verbose){write-host $error[0]};$failed = $true}
$tcpclient.Close()
}
if($failed){return $false}else{return $true}
}try {Restart-Computer $server -force -ErrorAction Stop}
catch {
$events += "Restart command was not accepted by $server`n"
write-host "Restart command was not accepted by $server`n"
$restart_failed = $true
}if (-not ($restart_failed)){
$events += "Restart request was accepted by the server at $((get-date).tolongtimestring())`n"
write-host "Restart request was accepted by the server at $((get-date).tolongtimestring())`n"
Write-Host "Waiting on RPC ping fail...`n"

$timer = [System.Diagnostics.Stopwatch]::StartNew()

$timer.reset()
$timer.start()

while ($timer.elapsed.totalseconds -lt $pingfail_timeout){
if(-not (test-port ($server))){
$events += "RPC ping fail detected at $((get-date).tolongtimestring())`n"
write-host "RPC ping fail detected at $((get-date).tolongtimestring())`n"
$RPC_pingfail = $true
break
}
}

Write-Host "Waiting on ICMP ping fail...`n"
while ($timer.elapsed.totalseconds -lt $pingfail_timeout){
if (-not (test-connection $server -Quiet)) {
$events += "ICMP ping fail detected at $((get-date).tolongtimestring())`n"
write-host "ICMP ping fail detected at $((get-date).tolongtimestring())`n"
$pingfail = $true
break
}
}

if (-not($pingfail)){
$events += "ICMP ping fail not detected in $pingfail_timeout seconds. Server appears to be hung.`n"
write-host "ICMP ping fail not detected in $pingfail_timeout seconds. Server appears to be hung.`n"
exit
}

Write-Host "Waiting on ping resume..."`n
$timer.reset()
$timer.start()
While ($timer.elapsed.totalseconds -lt $pingresume_timeout){
if (test-connection $server -Quiet){
$events += "ICMP ping resumed at $((get-date).tolongtimestring())`n"
write-host "ICMP ping resumed at $((get-date).tolongtimestring())`n"
$ping_resume = $true
break
}
}

while ($timer.elapsed.totalseconds -lt $pingresume_timeout){
if(test-port -server $server){
$events += "RPC ping resumed at $((get-date).tolongtimestring())`n"
write-host "RPC ping resumed at $((get-date).tolongtimestring())`n"
$RPC_pingresume = $true
break
}
}

if (-not($ping_resume)){
$events += "ICMP ping resume not detected in $pingresume_timeout seconds. Server appears to be hung.`n"
write-host "ICMP ping resume not detected in $pingresume_timeout seconds. Server appears to be hung.`n"
}

if ($ping_resume -and -not $rpc_pingresume){
$events += "RPC ping resume not detected in $pingresume_timeout seconds. Server appears to be hung.`n"
write-host "RPC ping resume not detected in $pingresume_timeout seconds. Server appears to be hung.`n"
exit
}

$events += "Waiting $servicecheck_delay seconds for service startup...`n"
write-host "Waiting $servicecheck_delay seconds for service startup...`n"

sleep -Seconds $servicecheck_delay

$events += gwmi win32_service -ComputerName $server |? {$_.startmode -eq "auto"} | ft state,name,status -auto | out-string
}

$events

}

monitored-restart ($args[0])

Скачать reboot.zip

Пожалуйста, оцените статью:
(всего оценок: 5, средняя: 4,80 из 5)