Using Powershell to stop and start dependent services with error notification

A few days ago I received a request to restart a set of dependent Hyperion services every Sunday. This had to be done because; “That’s what Oracle support said is the fix to one of our TAR’s”. Although this server has 3.75 GB of RAM and had never used more than 1.2 GB of RAM. Oracle claims that memory issues are causing a service to fail. This failure causes logons to fail. There are no events in the eventlogs or error information in any Hyperion logs that we can find. However, If you restart the services, then the problem goes away. So that is Oracle support’s answer, restart the services; “case closed”.

I do not call this a solution, but a kludge. Our Hyperion activity is relatively light. I guess Oracle’s answer to their very large and active customers must be to restart these services every 15 minutes. Hmmm, no let me think a second, the Hyperion product is financial planning software, with support answers like this, should I be concerned that this software might be calculating the wrong results? I wonder if I need to restart the other services frequently, just to be sure they calculate correctly?

Ok, my sarcasm and diatribe aside, I decided to create a PowerShell script and run it as a scheduled task.

I decided to take this opportunity to create a flexible script that I might have use for in the future. I decided:

  • If one of the stop or start operations fails, then stop processing and notify someone to take action via email.
  • I wanted a simple array that I would list services in the dependent stop order
  • The code would use the same array and start in the reverse order
## Reference to System.Net
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Net.Mail")
############################################
# sendEmail [-smtphost -from -to -subject -body ]
############################################
function sendEmail ($smtphost, $from, $to, $subject, $body)
{
#* Create new .NET object and assign to variable
$mail = New-Object System.Net.Mail.MailMessage
$mail.From = $from;
$mail.To.Add($to);
$mail.Subject = $subject;
$mail.Body = $body;
$smtp = New-Object System.Net.Mail.SmtpClient($smtphost);
$smtp.Send($mail);
}

# set this to your smtp server
$smpthost="your_smtp_server.yourdomain.com"
$thishost = $env:computername
# set this your from email address
$from = $thishost+"-alert-notifier@yourdomain.com"
$to = "alertme@yourdomain.com"

# stop in forward order, start in reverse order. These are the service names, not display names.
$svcs = @("service0", "service1", "service2")

# stop in forward order
for ($i=0; $i -le $svcs.Length - 1; $i++)
{
   stop-Service $svcs[$i]
   $service = get-service $svcs[$i]
   If ($service.status -ne "Stopped") {
      $dt = Get-Date;
      $subject="Error! unable to stop " + $svcs[$i] + " on host $thishost on $dt."
      $msgtext=$subject + "`nThe status is $service.status"
      sendEmail $smpthost $from $to $subject $msgtext
      exit
   }
}

# start in reverse order
for ($i=$svcs.Length - 1; $i -ge 0; $i--)
{
   start-Service $svcs[$i] 
   $service = get-service $svcs[$i] 
   If ($service.status -ne "Running") {
      $dt = Get-Date;
      $subject="Error! unable to start " + $svcs[$i] + " on host $thishost on $dt."
      $msgtext=$subject + "`nThe status is $service.status"
      sendEmail $smpthost $from $to $subject $msgtext
      exit
   }
}

A few other tidbits of information:

  • To make this run as a windows scheduled task you need to set the Task’s “Run:” field to”
  • C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -command "&{C:\fully-qualified-path\your_script.ps1}"
    
  • To run unsigned code in PowerShell you need to review PowerShell and code-signing.
    In PowerShell V2 you will be able to set a temporary bypass
  • powershell.exe –ExecutionPolicy Bypass -command "&{C:\fully-qualified-path\your_script.ps1}"
    

This script seems to be working pretty well.

BY the way, did you notice the `n above? Believe it or not, that is the PowerShell newline character. What was Microsoft thinking!? What was wrong with “\n” like most other languages? In case you are wondering, on the US keyboard, the ` is under the ~.

Be Sociable, Share!
This entry was posted in PowerShell and tagged , , . Bookmark the permalink.