Hello all, I posted about this previously but it was decided to take this a step further.

We have servers with services that do not always start on their own. They start if stopped, but they do not always start on their own; even after a reinstall and setting the service to a delayed start. Others are working on this part.

In the meantime, we would like a script that starts the services if stopped, waits, checks again, and emails out the results to let us know the services are started and/or others failed to start. I have gotten up to the script waiting and confirming the service status again and I am now stuck. I am looking into this on my own, but I am still very new to Powershell.

$ServiceName = 'service1','service2'
$arrService = Get-Service -Name $ServiceName

while ($arrService.Status -ne 'Running')
{

    Start-Service $ServiceName
    write-host $arrService.status
    write-host 'Services starting'
    Start-Sleep -seconds 60
    $arrService.Refresh()
    if ($arrService.Status -eq 'Running')
    {
        Write-Host 'Services are now Running'
    }

I’m only utilizing a script because it seems the most reliable (in this instance), and it’s free. However, if anyone knows of a free product that does this same thing, that is also welcome.

Thank you all.

4 Spice ups

where exactly are you stuck? sending them email? it seems to be looping and waiting?

What do you need help with?

I need to finish the script to email out to tell us if the services (individually) are started or stopped. Kind of like this:

“All requested services are running! (echo service names)”, or “Some services did not start (echo service names)”.

ok, what have you tried?

I don’t see any code about sending an email?

Do you want that status before you tried to restart , or after?

for this case i might not use a while as it might get stuck forever if the service does not come back up.

The email part is simple, thousands of examples on the WWW.
If it were me, I would choose how many service Starts I would tolerate before dropping out and going to the next server.
That is,

for ($i = 0; $i -LT $MaxTries; $i++) {
    # stuff to test for started service...
}
1 Spice up

i have something like this, not sure if that’s overkill

clear-host
$services = 'service1','service2'

$serviceReport = 
foreach($service in $services){
    $serviceStatus = Get-service $service
    
    if($serviceStatus.status -eq 'running'){
        $serviceStatus
    }
    else{
        start-service $service
        $statusReport = 
        for($c=0;$c -lt 6;$c++){
            $serviceStatus = Get-service $service
            Start-Sleep -Seconds 10
            if($serviceStatus.status -eq 'running'){
                $serviceStatus
                break
            }
        }
        $serviceStatus
    }
}

$serviceReport 

$mail = @{
        from       = "from@domain.com"
        to         = "to@domain.com"
        subject    = "Service Status"
        smtpserver = "smtp.server.domain"
        port       = "25"
        body       = $serviceReport | selectobject status,name | ConvertTo-Html | out-string
        bodyAsHTML = $true
    }
Send-MailMessage @mail

1 Spice up

There are some caveats to sending email with PowerShell on modern infrastructure. The native email commandlet Send-MailMessage is obsolete and not recommended because it only uses SMTP. It cannot handle modern encryption protocols. Its only there for compatibility and there are no plans for a direct replacement.

The recommended way is to use the MailKit library or use API calls. Check How to Send Email Securely with PowerShell for a good writeup.

The recommended way is to use the MailKit library or use API calls

Just curious, you got a source, I know ‘send-mailmessage’ is getting retired but I have not seen anything official from Microsoft.
Mailkit and API calls are just other ways to send mail, just never seen it recommended from MSFT, so just curious.

@tulioarends

I found out through a note on the online version of the Send-MailMessage documentation ( Send-MailMessage (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Learn ):

They added it to all versions, 5.1 to 7.2. I read the note mentioned in the message, it’s a post on the .Net GitHub. Seems likely that MailKit, which is a third party open source library, might be incorporated into .Net as a core component down the line.

In all honesty I think this is not a big issue if you have on-prem mail servers, but should be considered if you use a third party provider like Gmail, Microsoft 365, hosted Exchange, etc.

I’m aware of ‘send-mailmessage’ retiring but never heard of mailkit being the “official” replacement, that was my question.

Nothing official that I’ve seen. Seems likely to some people I asked about it who follow .Net development.

Take it as hearsay.

I personally prefer the API method, but that’s because we use M365 ang Google Workspaces.

1 Spice up

In terms of the initial post, you could use WMI and permanent eventing to detect any time that a service is not running. Build a permanent event handler which would require adding three objects to WMI. Then, each time that WMI detects that the service is not running, it runs a script. In that script, you check again to make sure the service is running and if not - start it. You might want to use Get-Upgime too in the script and ignore the service being down for say the first 10 minutes after the host comes up.
In my next PowerShell book, I demonstrate setting up a Perm Event Handler - see https://raw.githubusercontent.com/doctordns/PACKT-PS7/master/scripts/Ch%2015%20-%20WMI/15.7%20-%20Implementing%20Permanent%20WMI%20Event%20Handling.ps1 .
To adapt this you need to change the classes you are monitoring from the ds_groups class.

2 Spice ups