Author Posts

May 8, 2018 at 9:22 pm

Hi I'm new to PowerShell and was wondering if it is possible within PowerShell for it to scan a list of hosts and only reboot the hosts that needs it after the list of servers has been scanned. For example, I have three servers in this list the first and third server don't need a reboot but the second one does.

Currently when the script gets to the second server it does the reboot (and checks to make sure the server is up and IIS is up after the reboot) and then proceeds to scan the third server to see it doesn't need to be rebooted.

What I'd like to do is have the script scan all the servers in the list and then once the list is scanned reboot the servers needed.


$ServerList = get-content "C:\Users\Documents\FileCopy\uptime.txt"
$hour1 = (Get-Date).AddHours(-5)
$hour2 = Get-Date $hour1 -format g

#Check content of uptime.txt to ensure servers are listed.
If((Get-Content "C:\Users\Documents\FileCopy\uptime.txt") -eq $Null)
{
    Write-Verbose "File is empty and missing servers!  Please check the file." -verbose
    exit 1
}

Foreach ($server in $ServerList)
{
$wmi = Get-WmiObject -Class Win32_OperatingSystem -Computer $server
$lastRebootTime=$wmi.ConvertToDateTime($wmi.LastBootUpTime)
    If ($lastRebootTime -lt $hour2)
        { 
          Write-Verbose "Server $server needs to be rebooted" -verbose

          #Reboot command sent to server
          Invoke-Command -ComputerName $server -ScriptBlock { restart-computer -force -verbose }
          
          Write-Verbose "Waiting 3 minutes for remote host to restart..."
			Start-Sleep -Seconds 180
			write-host -BackgroundColor Black -ForegroundColor Magenta "done sleeping $(get-date -Format o)"
			if(!(Test-NetConnection -ComputerName $server -Port 3389).TcpTestSucceeded) #3389 is RDP
			{
				Write-Verbose "Windows Remote Desktop on $server is not up. Waiting 2 additional minutes for it to respond..."
				Start-Sleep -Seconds 120
				if(!(Test-NetConnection -ComputerName $server -Port 3389).TcpTestSucceeded)
				{
					Write-Host -BackgroundColor Black -ForegroundColor Red "ERROR: Windows Remote Desktop on $server is not up"
					Write-Host -BackgroundColor Black -ForegroundColor Red "Script Exiting, Please check server manually..."
					exit 1
				}
			}  
        }
    Else
       { Write-Verbose "Server $server does not need to be rebooted" -verbose }
}

May 8, 2018 at 11:06 pm

What I'd like to do is have the script scan all the servers in the list and then once the list is scanned reboot the servers needed.

So you need 2 independend loops.
1. Check for needed reboot and output the result to a variable
2. Use this variable to reboot the servers.

$ServerListFile = 'C:\Users\Documents\FileCopy\uptime.txt'

$ServerList = Get-Content -Path $ServerListFile
$FiveHoursAgo = (Get-Date).AddHours(-5)
If (-not $ServerList) {
    Write-Verbose "File is empty and missing servers!  Please check the file." -verbose
    exit 1
}

$RebootNeeded = Foreach ($Server in $ServerList) {
    $lastRebootTime = (Get-CimInstance -ClassName CIM_OperatingSystem -ComputerName $server).LastBootUpTime
    If ($lastRebootTime -lt $FiveHoursAgo) { 
        Write-Verbose "Server $server needs to be rebooted" -verbose
        $Server
    }
}

If ($RebootNeeded) {
    Foreach ($Server in $RebootNeeded) {
        Restart-Computer -ComputerName $Server -Force -Verbose -Wait 
    }
}

That's actually all you need. 😉