Solved

PowerShell Restart Servers Script

Posted on 2014-02-25
26
1,650 Views
Last Modified: 2014-03-07
Hi Guys,

I have have this server restart script:

$header = "server"
 
$servers = import-csv c:\path\to\ServersToReboot.csv -header $header
 
foreach($i in $servers) {
     Write-Host "Attempting to reboot:" $i.server "..."
 
     $serverObj = gwmi Win32_operatingsystem -computer $i.server
 
     $status = $serverObj.reboot()
 
     if ($status.ReturnValue = "0") {
          Write-Host "Reboot successful."
     } else {
          Write-Host "Reboot failed. Check permissions."
     }
}

However I need to reboot servers one at time, when one server comes back up then to reboot the next one, how can I do this?

Please help!

Thank you in advance.
0
Comment
Question by:Kay
  • 13
  • 6
  • 6
  • +1
26 Comments
 
LVL 34

Accepted Solution

by:
Dan Craciun earned 250 total points
ID: 39885708
The simplest way would be to add a pause
foreach($i in $servers) {
     Write-Host "Attempting to reboot:" $i.server "..."
 
     $serverObj = gwmi Win32_operatingsystem -computer $i.server
 
     $status = $serverObj.reboot()
 
     if ($status.ReturnValue = "0") {
          Write-Host "Reboot successful."
     } else {
          Write-Host "Reboot failed. Check permissions."
     }
    Start-Sleep -s 600  # this will wait for 10 minutes
}

Open in new window

HTH,
Dan
0
 
LVL 34

Expert Comment

by:Dan Craciun
ID: 39885724
Or, you can check network connectivity to the server, once every 5 seconds:
foreach($i in $servers) {
     Write-Host "Attempting to reboot:" $i.server "..."
 
     $serverObj = gwmi Win32_operatingsystem -computer $i.server
 
     $status = $serverObj.reboot()
 
     if ($status.ReturnValue = "0") {
          Write-Host "Reboot successful."
     } else {
          Write-Host "Reboot failed. Check permissions."
     }
    do {
        Start-Sleep -s 5  # this will wait for 5 seconds }
    while (!(Test-Connection -ComputerName $i -Quiet))
}

Open in new window

0
 

Author Comment

by:Kay
ID: 39885812
thanks Dan, Problem is that I need confirmation that my server is back online sometimes on my network the VM doesn't pick up an ip address so it requires another reboot.

If there was a way to ping the server to see that its back online, if it is then to continue the loop of restarting the other servers, hope this makes sense.

what does the -quite switch mean?
0
 

Author Comment

by:Kay
ID: 39885842
Also is there a way to check if there are any users logged in?
0
 
LVL 34

Expert Comment

by:Dan Craciun
ID: 39885863
Test-Connection pings the server :)

See here: http://technet.microsoft.com/en-us/library/hh849808.aspx

-Quiet will disable output and simply return True if the ping succeeded and False if not.

So this:
while (!(Test-Connection -ComputerName $i -Quiet))
will be true as long as the $i server does not anwer the ping. ! negates.
0
 
LVL 34

Assisted Solution

by:Dan Craciun
Dan Craciun earned 250 total points
ID: 39885904
The simplest way I know of to check for logged-on users is
Get-TSSession -ComputerName $i

You need the Terminal Services PowerShell Module, which you can get from here: http://archive.msdn.microsoft.com/PSTerminalServices

After install, you would do:
Import-Module PSTerminalServices
Get-TSSession -ComputerName "yourServer"

Open in new window

HTH,
Dan
0
 
LVL 68

Assisted Solution

by:Qlemo
Qlemo earned 167 total points
ID: 39885959
The only way to check for a VM starting, but not getting an IP, is to use the respective VM PS tools, like VMware PowerCLI. Without an IP the remote machine is not reachable otherwise.
0
 

Author Comment

by:Kay
ID: 39885971
thanks dan much appreciated, what I am thinking is to send an email for servers that fail the ping :)

So is the while (!(Test-Connection -ComputerName $i -Quiet)) only once inside the for loop, ow will it continue sending me emails until its back up?
0
 

Author Comment

by:Kay
ID: 39885994
Hi Dan,

that's my script so far will it work?

$header = "server"
 
$servers = import-csv c:\servers.csv -header $header

foreach($i in $servers) {
     Write-Host "Attempting to reboot:" $i.server "..."
 
     $serverObj = gwmi Win32_operatingsystem -computer $i.server
 
     $status = $serverObj.reboot()
 
     if ($status.ReturnValue = "0") {
          Write-Host "Reboot successful."
	Start-Sleep -s 300  # this will wait for 5 minutes
     } else {
          Write-Host "Reboot failed. Check permissions."
     }
    do {

	Send-MailMessage -To "test.test@test.ac.uk" -From "test@test.ac.uk" -SmtpServer 192.168.100.31 -Subject "$i ping failed" -Body "$i ping failed"	

        }
    while (!(Test-Connection -ComputerName $i -Quiet))
}

Open in new window


The idea is to reboot a server, then wait 5 minutes and then do a ping If that fails it will send us an email saying it failed and then continue rebooting the other servers.

Thank you soo much dan.
0
 
LVL 34

Assisted Solution

by:Dan Craciun
Dan Craciun earned 250 total points
ID: 39886015
You don't need a loop, or you'll end up with a full inbox if a server does not start.

Replace
  do {

	Send-MailMessage -To "test.test@test.ac.uk" -From "test@test.ac.uk" -SmtpServer 192.168.100.31 -Subject "$i ping failed" -Body "$i ping failed"	

        }
    while (!(Test-Connection -ComputerName $i -Quiet))

Open in new window


with
if (!(Test-Connection -ComputerName $i -Quiet)) {
    Send-MailMessage -To "test.test@test.ac.uk" -From "test@test.ac.uk" -SmtpServer 192.168.100.31 -Subject "$i ping failed" -Body "$i ping failed"
}

Open in new window

HTH,
Dan
0
 

Author Comment

by:Kay
ID: 39892084
Hi it don't seem to read the if (!(Test-Connection -ComputerName $i -Quiet))

instead it sends me the email. Please Help!
0
 

Author Comment

by:Kay
ID: 39892096
I've tried

if (Test-Connection -ComputerName $i -Quiet)
	{
    		Send-MailMessage -To "test@test.ac.uk" -From "test@test.ac.uk" -SmtpServer smtp.test.ac.uk -Subject "$i ping successful" -Body "$i ping successful"
	} 
	Else
		{

			Send-MailMessage -To "test@test.ac.uk" -From "test@test.ac.uk" -SmtpServer smtp.test.ac.uk -Subject "$i ping Failed" -Body "$i ping Failed"
		}

Open in new window


However for some reason it sends the email from the else statement?? even if the condition is true??
0
 
LVL 34

Expert Comment

by:Dan Craciun
ID: 39892160
Nope.
If it always sends the message from the Else statement, that means the condition is false.

Test the condition in PS and see if it works. Remove the -Quiet to see the output and errors.
I'm suspecting that $i does not resolve properly. DNS trouble.
0
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
LVL 39

Assisted Solution

by:footech
footech earned 83 total points
ID: 39892473
Given the earlier part of your script, the test-connection command probably needs to be
if (Test-Connection -ComputerName $i.server -Quiet)

I'm curious why you don't just use the Restart-Computer cmdlet.  It has parameters to wait for specified resources to be available, timeout, etc.
0
 

Author Comment

by:Kay
ID: 39894304
good question footech, I never knew about the restart-computer cmdlet! please let me know how I can use it for my purpose, its not just about the script its also about learning powershell.

Many thanks guys, I will give it the best grade I can when I close it.
0
 
LVL 68

Assisted Solution

by:Qlemo
Qlemo earned 167 total points
ID: 39894566
If you don't know anything about a cmdlet, or search for what could be fitting, use get-help or get-command with wildcards. E.g. for this case you can try:
 Get-Help restart-*
and you get at least two cmdlets (restart-computer and restart-service).
After you've spotted the probably correct cmdlet, get specific and detailed help with
 Get-Help -full restart-computer
Depending on your PS release (2.0 or 3.0), you get different syntax. 3.0 allows for more options, like waiting for completion, timeout etc.
0
 

Author Closing Comment

by:Kay
ID: 39894923
thank you all much appreciated!
0
 

Author Comment

by:Kay
ID: 39912198
Hi Guys,

I am trying to link the script that restarts the servers to another script to test the connection and restart the VM's using power cli, so far this is what I have written:

Add-PSSnapin VMware.VimAutomation.Core
$cred=get-credential
Connect-VIServer 10.2.32.4 –Credential $cred


Get-Content C:\Reboot_Servers.csv| % { if (!(Test-Connection -ComputerName $_ -Quiet))

$vm=get-vm "*" + $_ + "*"
Restart-VM -VM $VM
Start-Sleep -s 300  # this will wait for 5 minutes
   }

Open in new window


 and it needs to be run on another server with powercli installed, problem is that I wont be sitting on the computer when this command runs and the get-credential will prompt for credential and also how can I link this with my other script, restart server script?
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39912222
Live is much easier if you install PowerCLI on the machine you want to run the script on.
And I have no idea how you would want to link the scripts - they have no connection to each other. However, you can always just call another script within a script by providing the path:
<# code here #>
C:\Scripts\otherScript.ps1

Open in new window

0
 

Author Comment

by:Kay
ID: 39912229
thanks Qlemo, yea its a lot better I can install powercli on the server, but problem is it has to go through a lengthy change request at my organisation.
0
 

Author Comment

by:Kay
ID: 39912231
How can I get around the get-credential issue, where I can store this data so it wont prompt?
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39912491
You want to store the credentials, or to get asked locally instead of remote?
0
 

Author Comment

by:Kay
ID: 39912498
store credentials, so when I use windows task scheduler I wont get prompted for it, hope it makes sense.
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39912606
Is having the password in plain text in the script ok, or do you need better security?
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39912642
Plain text:
$cred = New-Object Management.Automation.PsCredential("Username",
  (ConvertTo-SecureString "Password" -AsPlainText -force))

Open in new window

Password hashed in a file:
$cred = New-Object Management.Automation.PsCredential("Username",
  (Get-Content C:\Passwordfile.txt | ConvertTo-SecureString))

Open in new window

and the file has been generated once with
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File C:\Passwordfile.txt

Open in new window

(to get a prompt) or
ConvertTo-SecureString "Password" -AsPlainText -Force | ConvertFrom-SecureString | Out-File C:\Passwordfile.txt

Open in new window

0
 

Author Comment

by:Kay
ID: 39912670
how would I reimport the password file in the get-credential? or anywhere else where it requires user names and password?
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Sometimes drives fill up and we don't know why.  If you don't understand the best way to use the tools available, you may end up being stumped as to why your drive says it's not full when you have no space left!  Here's how you can find out...
The recent Microsoft changes on update philosophy for Windows pre-10 and their impact on existing WSUS implementations.
This tutorial will walk an individual through locating and launching the BEUtility application to properly change the service account username and\or password in situation where it may be necessary or where the password has been inadvertently change…
This tutorial will show how to configure a single USB drive with a separate folder for each day of the week. This will allow each of the backups to be kept separate preventing the previous day’s backup from being overwritten. The USB drive must be s…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now