Search code examples
powershellpowershell-4.0

Problem with error handling and get service


I'm trying to get Powershell to;
Be able to stop/start services remotely.
Log as it goes, so if it needs to stop/start the service, it prints that out.
But a big issue I've come across is if the service doesn't exist, it spits out a huge error.
I'm still writing the rest of the script, this will be doing a number of things in terms of shutting down an application, but I don't know if that error will mean the rest of the script won't run.
There's an additional problem in that I'm not sure how to also put the WriteLog function in the second stage of the script.
Can I just put multiple {} section after an IF, so I can run the Stop as well as write to log?

The below code is just for stopping the service.
So it;
1. Reports the service is already stopped.
2. Stops it, if it isn't.
- Steps 1 and 2 work, if the service is there, it's 3 I'm having the issue with
3. If the service doesn't exist, I would like it to continue (Becuase it's not a problem the service doesn't exist) but print out that it doesn't, because they may prove useful to know

Note, the Write-Log, is a function to write to both a physical log file, and to the console at the same time.

IF (Get-Service -ComputerName localhost -Name ('ServiceName') | Where-Object {$_.Status -eq "Stopped"})
    {Write-Host "'ServiceName' is already stopped, proceeding..."}
ELSEIF
    (Get-Service -ComputerName localhost -Name ('ServiceName') | Where-Object {$_.Status -eq "Running"})
    {Get-Service -ComputerName localhost -Name ('ServiceName') | Stop-Service -Force}
ELSEIF 
    (Get-Service -ComputerName localhost -Name ('ServiceName') -ErrorAction "Continue")
    {Write-Host "'ServiceName' doesn't exist, proceeding..."}

Right now this prints out the error 3 times that the service can't be found.
I get that this is because it's failing to get the service before it even evaluates after being piped, whether it's stopped or not.
So I think the method I'm using is wrong entirely, but not sure where to go with it.
I would expect nothing to be printed except 'ServiceName doesn't exist, proceeding...'


Solution

  • Using IF statements in this way can quickly become out of hand. Also, you are getting the service many times in an unnecessary manner. You'd be better off using something like this:

    try{
        #Getting service - This way the service is only queried once, making the script fast among other things
        $service = Get-Service -Name 'Service Name' -ErrorAction Stop
    
        switch ($service.Status){
            'Stopped'{Write-Host "$($service.Name) is already stopped"}
            'Running'{Stop-Service $service -Force -ErrorAction Stop}
            Default{Write-Host 'Service is neither stopped or running'}
        }
    }catch{
        #Catching errors
        Write-Host 'Error'
    }