PS

How to reboot many computers at the same time (remotely)

IDrive Remote Backup

PowerShell is defined as a cross-platform task automation and configuration management framework. That means it was mainly created to automate your tasks. If you are a Windows system administrator, PowerShell should be your best friend in all your daily routines.

One of those routines is a periodic reboot of Windows servers (you should do it at least once a month after installing new patches). In this post, I will show you how to reboot as many servers as you want at the same time, and collect the reboot status for each of them.

Let’s start from the easiest step – reboot remotely one computer (computer name: MyServer1)

Restart-Computer -ComputerName MyServer1

In my examples, I will execute reboot processes from the domain admin session that has the same privileges on all rebooted servers. Otherwise, you need to the “-Credential” parameter. E.g.:
$Cred = Get-Credential
Restart-Computer -ComputerName “MyServer1” -Credential $Cred

The command above does the job, but it doesn’t return the reboot results, so you do not know if the server was successfully rebooted.
So let’s try to add a few helpful parameters:

Restart-Computer -ComputerName MyServer1 -Wait -For Wmi -Timeout 600 -Force

In the example above I execute the reboot on the MyServer1 computer and wait until receiving a reply to a Win32_ComputerSystem query for the MyServer1. I also added a timeout of 600 seconds (10 minutes) to get an error if the computer is not rebooted in 10 minutes.
To reboot more than one computer, you can add more computer names to the ComputerName parameter:
-ComputerName MyServer1, MyServer2, MyServer3

It looks almost great, but I prepared a script that automates the whole rebooting process (including stopping and starting processes) and I wanted to have the reboot under better control. So I prepared a robust solution that executes each reboot as a separate asynchronous job and collects results when all jobs are completed.
The script can look like that:

#define the script that will be executed for each computer
$script = {
    $computer = $args[0]
    try {
        Restart-Computer -ComputerName $computer -Wait -For Wmi -Timeout 600 -Force -ErrorAction Stop
        Return New-Object PSObject -property  @{status = 'OK'; computer = $computer; error = ''}
    } catch {
        Return New-Object PSOobject -property  @{status = 'ERROR'; computer = $computer; error = ($Error[0].Exception.Message)}
    }
}

#start asynchronous jobs for each computer (all jobs will be executed at the same time)
Start-Job -Name 'reboot' -ScriptBlock $script -ArgumentList 'MyServer1' | Out-Null
Start-Job -Name 'reboot' -ScriptBlock $script -ArgumentList 'MyServer2' | Out-Null
Start-Job -Name 'reboot' -ScriptBlock $script -ArgumentList 'MyServer3' | Out-Null

$rebootResults = @()

#wait until all jobs are finished and collect results
While (Get-Job | Where {$_.State -eq 'Running' -and $_.name -eq 'reboot'}) {
  Start-Sleep -Milliseconds 500   
  $rebootResults += Receive-Job -Name 'reboot'
}

#display results of servers rebooting
$rebootResults | Select-Object status, computer, error | Format-Table


If you like this post, please share it and leave a comment.

Share this post:

Share on facebook
Share on google
Share on twitter
Share on linkedin
Share on email