PowerShell: Reboot remote computers

PowerShell logo

It looks like it’s going to be a week of scripting blog posts.  Today’s script is used to reboot a list of remote computers.  Sometimes, when deploying security patches, the computers fails to reboot.  So I use this script to force reboots.  It would be a piece of cake to modify the script, so that it turns off the computers instead.

One of my customers should find that useful.  Out of 2000 computers, about 150 computers get left powered on over the weekend.

What the script does:

  • reads the list of computers to be reset from C:\computer_lists\reboot_target_list.txt
    the format of the list is COMPUTERNAME,Reboot Reason
  • “Pings” the computer to see if it’s on the network.
  • checks to see if someone is logged on.  If someone is, don’t reboot.
  • reboots the computer.

Check and reboot computers.ps1

Clear-Host

$ok_does_not_exist = $True
$date = ( get-date ).ToString('yyyyMMdd')
$reboot_logfile = "C:\computer_lists\output\$date-check_and_reboot_computers.txt"

#check that the pc-list file does exist.
$file_exist_reboot_list = (Test-Path C:\computer_lists\reboot_target_list.txt)

# if it does, do some process (check that it's pingable, has assorted files etc.
if (! $file_exist_reboot_list)
{
exit
}
#endif

$reboot_pcs = (Get-Content C:\computer_lists\reboot_target_list.txt)
foreach ($pc_to_be_rebooted in $reboot_pcs)
{
$access_denied_error = $False
# get the first comma position
$string_delimiter_position_1  = $pc_to_be_rebooted.indexof(",")
# get the server name
$pc_name = $pc_to_be_rebooted.substring(0,$string_delimiter_position_1)

        $pc_name + ": checking PC" | Out-File $reboot_logfile -append
#
$reboot_reason = $pc_to_be_rebooted.substring($string_delimiter_position_1 + 1,$pc_to_be_rebooted.length - $string_delimiter_position_1 - 1)
$address_string = "Address=" + "'" + $pc_name +"'"
$ping = Get-WmiObject -Class Win32_PingStatus -Filter $address_string
if ($ping.StatusCode -ne 0)
{
Write-Host Server: $pc_name - Not pingable
$pc_name + ": not pingable, skipping" | Out-File $reboot_logfile -append
}

        Trap [System.UnauthorizedAccessException]{
write-host "Problem encountered with $pc_name - Access denied"
$access_denied_error = $True
continue;
}
$wmi_status = (Get-WmiObject -query "select * from win32_service where name='Winmgmt'" -computername $pc_name)
if ($wmi_status.status -ne "OK")
{
$pc_name + ": WMI not accessible, skipping" | Out-File $reboot_logfile -append
Write-Host Server: $pc_name - WMI not accessible
$access_denied_error = $True
}
If ($access_denied_error)
{
Write-Host Server: $pc_name access denied
}
else
{
$objWMI_pc_computer_system = Get-WmiObject -Class Win32_ComputerSystem -computername $pc_name
If ($objWMI_pc_computer_system.UserName.length -ge 0)
{
$pc_name + ": user logged on - skipping " + $objWMI_pc_computer_system.UserName | Out-File $reboot_logfile -append
Write-Host $pc_name ": user logged on - " $objWMI_pc_computer_system.UserName
}
else
{
$objWMI_pc_os = Get-WmiObject -Class Win32_operatingsystem -computername $pc_name
$objWMI_pc_os.reboot()
$pc_name + ": rebooting" | Out-File $reboot_logfile -append
Write-Host $pc_name ": sent reboot"
}
}
}
exit

You can download the script here.

Bookmark and Share