none
Powershell script to check service status

    Question

  • Hello Experts,

    I'm newbie to Powershell.

    below is the my simple script to check service status, but whenever I run this, it gives me log "service is already started and running" although service is stopped. 

    can somebody guide me on this?

    -----------------------

    $Computer = “localhost”
    $Service = get-service -Computername $Computer
    $Srv = “BITS”
    $log = New-Item -type file -force “C:\ServiceStatus.txt”
    $Logtime = Get-Date -Format “MM-dd-yyyy hh-mm-ss”
    if ($Service.name -eq $srv)

    if ($Service.status -eq “Running”)
    {
    Write-output “$Srv service is already started and running: $Logtime” | Out-File $log -Append
    }
    elseif ($Service.status -eq “Stopped”)
    {
    Start-Service -InputObject (get-Service -Computername $Computer -Name $srv)
    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append
    }
    }

    -------------------------------

    Thanks in advance


    • Edited by samtiger Wednesday, July 23, 2014 8:34 AM
    Wednesday, July 23, 2014 8:33 AM

Answers

  • $Service = get-service -Computername $Computer
    is returning many services

    Just the BITS Services

    $SRV= "BITS"
    $Service = get-service -Computername $Computer | Where Name = $SRV


    OR To Loop Through services

    $Service = get-service -Computername $Computer
    FOREACH ($S in $Sevice)

    if ($S.name -eq $srv)

    if ($S.status -eq “Running”)
    {
    Write-output “$Srv service is already started and running: $Logtime” | Out-File $log -Append
    }
    elseif ($S.status -eq “Stopped”)
    {
    Start-Service -InputObject (get-Service -Computername $Computer -Name $srv)
    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append
    }
    }
    }

    Another thing, when you write out some thing in the write-output, write out what you are getting not what you're expecting

    for example

    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append

    Vs.

    Write-output “$S.Name was stopped, Service started now: $Logtime” | Out-File $log -Append

    • Edited by Brian Nadjiwon Wednesday, July 23, 2014 9:05 AM
    • Marked as answer by samtiger Wednesday, July 23, 2014 9:39 AM
    Wednesday, July 23, 2014 8:52 AM
  • Hi There

    I just made small modification :P I leave it to you to understand why :D

    $Computer = “localhost”
    $Srv = “BITS”
    $Service = get-service -Computername $Computer -name $Srv
    $log = New-Item -type file -force “C:\ServiceStatus.txt”
    $Logtime = Get-Date -Format “MM-dd-yyyy hh-mm-ss”
    if ($Service.name -eq $srv)
    { 
    if ($Service.status -eq “Running”)
    { 
    Write-output “$Srv service is already started and running: $Logtime” | Out-File $log -Append
    }
    elseif ($Service.status -eq “Stopped”)
    {
    Start-Service -InputObject (get-Service -Computername $Computer -Name $srv)
    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append
    }
    }

    Have fun Scripting :P

    Farhad

    • Proposed as answer by Farhad Farahi Wednesday, July 23, 2014 9:29 AM
    • Marked as answer by samtiger Wednesday, July 23, 2014 9:39 AM
    Wednesday, July 23, 2014 8:54 AM

All replies

  • You're getting all the services on the computer, then asking that collection if it's name equals 'BITS' and then if it's status equals running. PowerShell is checking that that collection contains a service with a name equal to $srv then checking to see if there's a service that's started. It doesn't care if they're different services.

    I'm sure jrv or molinjr will be along to explain why that happens but even i know that's not right.

    If you change the $service call to something like this:

    Get-Service -ComputerName localhost | ? {$_.Name -eq $Srv}

    Then that will get you the one service you're interested in.





    Wednesday, July 23, 2014 8:48 AM
  • $Service = get-service -Computername $Computer
    is returning many services

    Just the BITS Services

    $SRV= "BITS"
    $Service = get-service -Computername $Computer | Where Name = $SRV


    OR To Loop Through services

    $Service = get-service -Computername $Computer
    FOREACH ($S in $Sevice)

    if ($S.name -eq $srv)

    if ($S.status -eq “Running”)
    {
    Write-output “$Srv service is already started and running: $Logtime” | Out-File $log -Append
    }
    elseif ($S.status -eq “Stopped”)
    {
    Start-Service -InputObject (get-Service -Computername $Computer -Name $srv)
    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append
    }
    }
    }

    Another thing, when you write out some thing in the write-output, write out what you are getting not what you're expecting

    for example

    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append

    Vs.

    Write-output “$S.Name was stopped, Service started now: $Logtime” | Out-File $log -Append

    • Edited by Brian Nadjiwon Wednesday, July 23, 2014 9:05 AM
    • Marked as answer by samtiger Wednesday, July 23, 2014 9:39 AM
    Wednesday, July 23, 2014 8:52 AM
  • Hi There

    I just made small modification :P I leave it to you to understand why :D

    $Computer = “localhost”
    $Srv = “BITS”
    $Service = get-service -Computername $Computer -name $Srv
    $log = New-Item -type file -force “C:\ServiceStatus.txt”
    $Logtime = Get-Date -Format “MM-dd-yyyy hh-mm-ss”
    if ($Service.name -eq $srv)
    { 
    if ($Service.status -eq “Running”)
    { 
    Write-output “$Srv service is already started and running: $Logtime” | Out-File $log -Append
    }
    elseif ($Service.status -eq “Stopped”)
    {
    Start-Service -InputObject (get-Service -Computername $Computer -Name $srv)
    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append
    }
    }

    Have fun Scripting :P

    Farhad

    • Proposed as answer by Farhad Farahi Wednesday, July 23, 2014 9:29 AM
    • Marked as answer by samtiger Wednesday, July 23, 2014 9:39 AM
    Wednesday, July 23, 2014 8:54 AM
  • Three incomplete guesses.  Pretty good.

    What happens if the service doesn't exist?

    By the way, the BITS service is set to "Manual" and is started when needed.

    Look closely at how this is structured and how it incorporates PowerShell techniques into a clear simple statement of flow.  It is clear what it does and easy to adjust.  One more step and you have a function.

    $computer=env:computername
    $srvname='BITS'
    $logfile='C:\ServiceStatus.txt'
    
    if($service=get-service $srvname -Computername $Computer){
         if($service.status -eq 'Running'){ 
             Write-output "$srvname service is already started and running:$([datetime]::Now)" | Out-File $log -Append
         }elsei{
              Start-Service $service
              Write-output "$srvname was stopped, Service started now: $([datetime]::Now)" | Out-File $log -Append
         }
    }else{
         Write-output "$srvname service not found on $computer:$([datetime]::Now)" | Out-File $log -Append
    }
    
    
     

    Once you actually understand how the CmdLets and objects work then it becomes clear that it is not necessary to write so much code.


    ¯\_(ツ)_/¯


    • Edited by jrv Wednesday, July 23, 2014 9:21 AM
    Wednesday, July 23, 2014 9:20 AM
  • Thanks Farhad & Brian

    It worked for me and I understood the logic as well :)

    But there is little problem with logs, instead of appending log, the script overwrites the existing logs. how to get rid out of this?

    Thanks again.

     

    Wednesday, July 23, 2014 9:23 AM
  • Use the append flag on Out-File to add to an existing file or create one if none exist.

    -Append

    Wednesday, July 23, 2014 9:28 AM
  • Hi There

    I just made small modification :P I leave it to you to understand why :D

    $Computer = “localhost”
    $Srv = “BITS”
    $Service = get-service -Computername $Computer -name $Srv
    $log = New-Item -type file -force “C:\ServiceStatus.txt”
    $Logtime = Get-Date -Format “MM-dd-yyyy hh-mm-ss”
    if ($Service.name -eq $srv)
    { 
    if ($Service.status -eq “Running”)
    { 
    Write-output “$Srv service is already started and running: $Logtime” | Out-File $log -Append
    }
    elseif ($Service.status -eq “Stopped”)
    {
    Start-Service -InputObject (get-Service -Computername $Computer -Name $srv)
    Write-output “$Srv was stopped, Service started now: $Logtime” | Out-File $log -Append
    }
    }

    Have fun Scripting :P

    Farhad


    elseif is unnecessary.  Think about how the logic works.

    ¯\_(ツ)_/¯

    Wednesday, July 23, 2014 9:45 AM
  • Only if the status is a binary flag, you can also have starting and stopping.
    Wednesday, July 23, 2014 9:47 AM
  • You're getting all the services on the computer, then asking that collection if it's name equals 'BITS' and then if it's status equals running. PowerShell is checking that that collection contains a service with a name equal to $srv then checking to see if there's a service that's started. It doesn't care if they're different services.

    I'm sure jrv or molinjr will be along to explain why that happens but even i know that's not right.

    If you change the $service call to something like this:

    Get-Service -ComputerName localhost | ? {$_.Name -eq $Srv}

    Then that will get you the one service you're interested in.





    Get-Service BITS

    Works just fine.  Why use a pipeline and return all services.  If you want to scan 500 system this will take a long time.

    The added info is to try and get people who have no programming experience to rethink how they approach things.  Programming takes a different way of seeing things.  One day it will click and you will see why.  Until then you will do things in odd and inefficient and possible wrong ways.  Bad programming leads to bad information.  Decisions based on bad information can be costly and destructive.  Take that from those of us who have been doing this for decades.  Don't thumb your nose at good programming practices.


    ¯\_(ツ)_/¯

    Wednesday, July 23, 2014 9:51 AM
  • Only if the status is a binary flag, you can also have starting and stopping.

    If you want to case all possibilities than you must include all possibilities.  Casing only two gives you a fall through.

    The whole design is actually unnecessary.  We can just to this and be done with  it:

    Get-Service BITS -CN somepc | Start-Service

    The only thing needed is to choose to handle the issue with no response and no service.  THe rest of the code is unnecessary if what is wanted is to always start a stopped service.

    My point was that you and the OP need to think more completely about what you are trying to do. if/elseif/else. Always "elseif" all possibilities or "else" the remainder

    If has a cousin that is logically identical bu syntactically different.  It is called a "switch" statement.  case/case/default - same structure.  In case we normally always include "default".


    ¯\_(ツ)_/¯

    Wednesday, July 23, 2014 9:57 AM
  • That is true but different to saying the elseif is unnecessary. Sometimes a one-liner is more hindrance than help and that qualified.
    Wednesday, July 23, 2014 10:02 AM
  • Change Log:

    env:computername will not resolve 'as is' for this variable.

    ElseIf is not needed (and mis-spelled in the example).

    *******************************************

    $Computer=(Get-ChildItem env:computername).value
    $srvname='BITS'
    $logfile='C:\ServiceStatus.txt'

    if($service=get-service $srvname -Computername $Computer){
         if($service.status -eq 'Running'){
             Write-output "$srvname service is already started and running:$([datetime]::Now)" | Out-File $log -Append
         }else{
              Start-Service $service
              Write-output "$srvname was stopped, Service started now: $([datetime]::Now)" | Out-File $log -Append
         }
    }else{
         Write-output "$srvname service not found on $Computer : $([datetime]::Now)" | Out-File $log -Append
    }

    Saturday, March 18, 2017 3:17 AM
  • $computername = $env:COMPUTERNAME

    \_(ツ)_/

    Saturday, March 18, 2017 5:08 AM