Get-Service with if/else checks

All,

I could use some guidance. I am new to this whole PowerShell scripting world so please excuse my ignorance in many areas.

I am trying to write a PS that checks a list of servers to see if its available for a list of specific services. I want the script to check if the service exists and start the service if it is not running. I also want the script to skip/ignore services that are not installed on those machines or are already running. I found many examples online of similar stuff but I am getting mixed results with those codes because they will falsely report a service as not installed or will say starting when its already running.

Can anyone help me to identify how I an fix it to make it run correctly?

$Servers = Get-Content "C:\<file location>\Desktop\Machines.txt"
$Services = Get-Content "C:\<file location>\ServiceList.txt"
foreach ($Computer in $Servers)
{
  if ((Test-Connection -ComputerName $Computer -Count 1 -Quiet) -ne $true)
  {
    Write-Host "Not able to connect to $Computer. Might be down or not exist" -ForegroundColor Red
  }
  else
  {
    Write-Host "Able to connect to $Computer. Checking Service Status" -ForegroundColor Green
    foreach ($Service in $Services)
    {
      $GS = Invoke-Command -ComputerName $Computer -ScriptBlock {Get-Service -Name "$Service" }
      if ($GS.Status -eq "Running")
      {
        Write-Host "$service is running on $Computer" -ForegroundColor Green
      }
      $GS = Invoke-Command -ComputerName $Computer -ScriptBlock {Get-Service -Name "$Service" } -ErrorAction SilentlyContinue
      if ($GS.Status -eq $null)
      {
        Write-Host "$service does not exist on $Computer" -ForegroundColor Yellow
      }
      $GS = Invoke-Command -ComputerName $Computer -ScriptBlock {Get-Service -Name "$Service" }
      if ($GS.Status -eq "Stopped")
      {
        Invoke-Command -ComputerName $Computer -ScriptBlock {Get-Service -Name "$Service" | Start-Service}
        Write-Host "$service is now started on $Computer" -ForegroundColor Green
        start-sleep -Seconds 5
      }
      
    }
  }
}

Landon,
Welcome to the forum. :wave:t4:

Since I like re-usable output I’d use a slightly different approach and avoid Write-Host prosa with fancy colors … :wink:

Besides this I’d recommend to avoid connecting to one computer more than once at a time.

$ComputerList = Get-Content -Path 'C:\<file location>\Desktop\Machines.txt'
$ServiceQueryList = Get-Content -Path 'C:\<file location>\ServiceList.txt'

$Result =
foreach ($ComputerName in $ComputerList) {
    if (Test-Connection -ComputerName $ComputerName -Count 1 -Quiet) {
        Invoke-Command -ComputerName $ComputerName -ScriptBlock {
            $ServiceList = 
                Get-Service -Name $USING:ServiceQueryList -ErrorAction SilentlyContinue
            foreach ($Service in $USING:ServiceQueryList) {
                $ServiceMatrix = 
                [ordered]@{
                    Name         = ''
                    Installed    = $false
                    Status       = 'n/a'
                    DisplayName  = 'n/a'
                }
                
                if ($Service -in $ServiceList.Name ) {
                    $CurrentService = 
                        $ServiceList | 
                            Where-Object -Property Name -EQ -Value $Service
            
                    $ServiceMatrix.Name = $CurrentService.Name
                    $ServiceMatrix.Status = $CurrentService.Status
                    $ServiceMatrix.Installed = $true
                    $ServiceMatrix.DisplayName = $CurrentService.DisplayName
                }
                else {
                    $ServiceMatrix.Name = $Service
                }
                [PSCustomObject]$ServiceMatrix

                $ServiceList | 
                    Where-Object -Property Status -EQ -Value Stopped | 
                        Start-Service -ErrorAction SilentlyContinue
            }
        } | 
            Select-Object PSComputerName, Name, Installed, Status, DisplayName
    }
    else {
        $ComputerUnreachableList += $ComputerName
    }
}

$Result | 
    Format-Table -AutoSize

'Computers unreachable: {0}' -f ($ComputerUnreachableList -join ', ')

This way you could use the output of the variable $Result to pipe it to Export-Csv for logging purposses or just for documentation. And even if you don’t - it is at least much easier on the eyes. :wink:

And you could use the output of the variable $ComputerUnreachableList for further steps or for investigations why these comptuers are unreachable. :+1:t4:

1 Like

Olaf,

Thank you for the script adjustments and wow that’s a lot to digest for me.

When I run this against a test list in ISE as admin, the script launches but then just sits there. Since I am just starting out, my question is if I am missing something?
I was also curious what the $QueryList on line 9 is referencing as I don’t see that reference anywhere else in the script. Was that supposed to say ServiceQueryList?
I also do not see where my section anymore about if the service is in a stopped state, to start it. Was my line of thinking incorrect and its done differently in your version?

Probably not. I’ve made a mistake copying different parts from different editors together. I corrected it.
I’d recommend to test it with only a few computers and only a few services.

Sorry. That was a copy and paste error when I pieced together the different parts of code. I corrected the code in my answer above. Try it now.

That’s done in line 34 to 36. :wink:

1 Like

You are awesome! That worked extremely well on our test set. I see what you were saying about connecting for each service and just do the connection once and wrap the service check itself within the if statement instead of outside it. I also need to get better at utilizing arrays as your solution provides a much cleaner run of everything.

I somehow completely overlooked line 34-36; right there in black and white lolol

Once again I cant thank you enough for the assistance. I knew I was on the right path but also knew I was in over my head a little bit.