Powershell script to start services.

Borislav Vitanov 81 Reputation points
2021-02-24T12:51:23.867+00:00

Hi guys,
I have little bit annoying problem with some services by me. In general by a reboot everything is fine, but the issues come when there are windows update, sometimes they caused services to hang, or took very long etc. So to fix it, I search, test some stuff and create a scheduled task to run 1 hours of the reboot to check for stopped services and run them.

# Start specific automatic start services not running
$server = "server1.domain.com"
$stoppedServices = (Get-WmiObject Win32_Service -ComputerName $server | Where-Object {$_.StartMode -eq 'Auto' -and $_.State -ne "Running"}).Name
foreach ($stoppedService in $stoppedServices) {
  Write-Host -NoNewline "Starting Server/Service: "; Write-Host -ForegroundColor Green $server"/"$stoppedService
  Get-Service -ComputerName $server -Name $stoppedService | Start-Service
}

or for example the Citrix services:

# Script to Manage the Citrix Services at an Citrix Session Host

Get-Service Citrix* -ErrorAction SilentlyContinue | Start-Service -ErrorAction SilentlyContinue
Get-Service CTX* -ErrorAction SilentlyContinue | Start-Service -ErrorAction SilentlyContinue
Get-Service BrokerAgent,CdfSvc,MRVCSvc,cpsvc,PvsVmAgent,ServicesManager,StackControlService -ErrorAction SilentlyContinue | Start-Service -ErrorAction SilentlyContinue

which is working fine. I use it as well manually in some cases instead of checking services.msc or server manager. My issue is with 3 different servers:
Wsus server where we have:

  • Windows Internal Database with MSSQL$MICROSOFT##WID
  • and WsusService
    there, I have an issue with starting the DB and then start the services. Basically it should try to start the DB, wait, check again if the DB is running and after this restart WSUSservice if running or start if stopped.

TMMS server where I have: MSSQL$TMMS , TMMSManagementService, MSCSService which should start in this order. I have here some cases when I have to execute manually MSSQL$TMMS 1-2 times because I got Service start time out. And after this I should start the Management service and then MSCSservice (which sometimes starts although others are stopped, and I have to restart when others are up.

But the most annoying server is the Skype for Business server, where I have 3 SQL services and almost 20 Skype for Business services. The Front-End service for examples needs sometime 20 minutes to start while all other services are already running. As SQL I have MSSQL$LYNCLOCAL, MSSQL$RTC, MSSQL$RTCLOCAL.

So, any advice how to make all this start and wait and check again and then continue with others structure? I guess for the $ and # , I have to use ' instead of " , right?

Thanks in advance

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,402 questions
0 comments No comments
{count} votes

8 answers

Sort by: Newest
  1. Borislav Vitanov 81 Reputation points
    2021-03-12T14:54:49.613+00:00

    Hi @MotoX80

    for some reason my previous comment is missing, so I have to write it again.
    I've tested on one server with manual, and automatic reboot and everything worked so far. Well now, the big test is coming cause now the windows updates are coming and see how it works with time-outs.
    By the way, just to be sure.
    Which row is for SQL services (the main services) and which one for the services depending on then and to be checked as well if they are running.
    For example as I mentioned at first - group 1 - SfB SQL Services, group 2 - SfB Services.
    Thanks

    0 comments No comments

  2. MotoX80 32,091 Reputation points
    2021-02-26T14:35:53.927+00:00

    I had a bug. I also added some more displays. Use this Starter function.

    Function Starter {
        write-host "Selection criteria is:" 
        $TheseSvcs | write-host 
        ""
        $StartDate = Get-Date              # start the clock
        write-host "Processing these services." 
        $svcs = $TheseSvcs | Get-Service
        $svcs | Format-table -Property Name, DisplayName, StartType, Status  | Out-String | Write-Host 
        while ($true) {
            $svcs = $TheseSvcs | Get-Service  | Where-Object  {$_.Status -ne 'Running'}  
            "We found {0} stopped services." -f $svcs.count | Write-Host
            if ($svcs.count -eq 0) {
                $script:success = $true              # update variable in correct scope
                break                               # All start=auto services in that group are running 
            }
            Write-Host "Starting the services" 
            $svcs | Start-Service -ErrorAction SilentlyContinue
            Start-Sleep -Seconds 30                    # give them some time to fire up 
            $svcs = $TheseSvcs | Get-Service  | Where-Object  {$_.Status -ne 'Running'} 
            "We found {0} services that did not start." -f $svcs.count | Write-Host
            if ($svcs.count -eq 0) {          
                $script:success = $true         # update variable in correct scope
                break                          # All start=auto services in that group are running 
            }
            $svcs | Format-Table -Property Name, DisplayName  | Out-String | Write-Host  
            $EndDate = Get-Date            # how long have we been running
            if ((NEW-TIMESPAN –Start $StartDate –End $EndDate).Minutes -gt $MaxRetryMinutes) {
                Write-Host "The services did not start wtihin the max wait limit." 
                $script:success = $false              # update variable in correct scope
                break  
            }
            Start-Sleep -Seconds 30             # How often should we retry? 
            Write-Host  "Retrying" 
        }
        write-host "Starter is ending. Current status:"
        $svcs = $TheseSvcs | Get-Service
        $svcs | Format-table -Property Name, DisplayName, StartType, Status  | Out-String | Write-Host 
    }
    
    0 comments No comments

  3. Borislav Vitanov 81 Reputation points
    2021-02-26T12:24:26.583+00:00

    Hi @MotoX80

    I've tried but it didn't start services. I've stopped them manually and executed it over ISE as Administrator.

    72502-services.jpg

    Thanks

    0 comments No comments

  4. MotoX80 32,091 Reputation points
    2021-02-25T16:34:31.727+00:00

    But for some reasons it doesn't detect properly the MSSQL$TMMS service

    You need a comma after $_. That statement would need to be:

     $svc = Get-Service -Name $_, 'MSSQL$TMMS', TMMSManagementService, MSCSService
    

    But that would mean that $svc is going to be a collection of services, and for every name in $Servicenames you would also process those 3 extra services. The rest of the code looks like it is expecting $svc to contain a single service object.

    I would think that you would want to include "'MSSQL$TMMS', "TMMSManagementService", "MSCSService"" in the $Servicenames variable.

    Rich's point about dependencies got me to realize that I was thinking too much about how I did patching. I didn't name services, I worked with the app support teams and I basically dictated that any service that they needed to be running after a patch cycle and reboot had to be set as start=auto. That's what my VB script looked at.

    Since you're identifying the names, you could include the names of any dependent services, and start=auto isn't necessarily a requirement. And we need to account for starting/stopping statuses.

    So, line 16 in my script should be:

    $svcs = $TheseSvcs | Get-Service  | Where-Object  ($_.Status -ne 'Running') 
    
    0 comments No comments

  5. Borislav Vitanov 81 Reputation points
    2021-02-25T14:17:14.857+00:00

    Hi to everyone,
    thank you for your answers. I will check the Starter function to see how it will work. In general, the patching is ok. I've modified and organize a PS script to install updates in background which works pretty fine. The problem is with the updates itself. For example, the server is rebooted, then it begins to install the updates, get to 33 % then make a reboot again and continues, then finally reboot, which I find pretty annoying. Then even that services are set to automatic delayed start, usually they hang. I can give you an example another annoying thing by SfB. It has 19-20 services which starts fast except the Front-End, which needs 15-20 minutes to start and suddenly the Front-End stops one the SfB services which makes no sense.

    I've tried this script as well:

    $serviceNames | Foreach-Object -Process {
      $svc = Get-Service -Name $_ "'MSSQL$TMMS', "TMMSManagementService", "MSCSService""
      if ($svc.Status -ne 'Running') {
        $svc.Start()
        while ($svc.Status -ne 'Running') {
          Write-Output "Waiting for $($svc.Name) to start, current status: $($svc.Status)"
          Start-Sleep -seconds 5
        }
      }
      Write-Output "$($svc.Name) is running"
    }
    

    But for some reasons it doesn't detect properly the MSSQL$TMMS service and continues with others. I put it in ' instead of " and still not work.
    Thanks

    0 comments No comments