Taskill & program restart on multiple computers with Powershell

63 views Asked by At

I am looking to kill and restart a specific task if it is anything other than running on multiple remote machines without using WinRM or pskill. I have come up with the following code.

When the task is running on all the machines, I will get

computer1 Service is running,
computer2 Service is Running,
...

When the service is not running (stuck in a pending state seems to be the biggest culprit) the script will error out.

If single target a machine by #ing out all the others, it will work just fine. I have another script that tells me what machines are running and what machines are not/pending.

$ComputerName = 
'computer1'
'computer2',
'computer3', 
'computer4',
'computer5',
'computer6',
'computer7',
'computer8'

Foreach ($Computer in $ComputerName)
{
  $ServiceName = 'name'
  $ServiceInfo = Get-Service -Name $ServiceName -ComputerName $ComputerName
  if ($ServiceInfo.status -eq 'Running') {
    Write-Host $Computer 'Service is Running'
  }
  While ($ServiceInfo.status -ne 'Running') {
    taskkill /s $ComputerName /IM 'ApacheWebServices.exe' /F
    Write-Host $ServiceInfo.Status
    $ServiceInfo | Set-Service -status Running
    Write-Host "Service starting"
  }
}
1

There are 1 answers

1
derpirscher On
While ($ServiceInfo.status -ne 'Running') {
    taskkill /s $ComputerName /IM 'ApacheWebServices.exe' /F
    Write-Host $ServiceInfo.Status
    $ServiceInfo | Set-Service -status Running
    Write-Host "Service starting"
}

Will run into an endless loop of killing and starting the service because you never update the $ServiceInfo, thus $ServiceInfo.status will be stuck at whatever the initial reading was.

The least thing you need to add in this loop is

While ($ServiceInfo.status -ne 'Running') {
    taskkill /s $ComputerName /IM 'ApacheWebServices.exe' /F
    Write-Host $ServiceInfo.Status
    $ServiceInfo | Set-Service -status Running
    Write-Host "Service starting"

    # optionally, add some delay here before requesting a new status

    # Request a new service status
    $ServiceInfo = Get-Service -Name $ServiceName -ComputerName $ComputerName
}

or alternatively

While (...) {
  ...
  $ServiceInfo = ($ServiceInfo | Set-Service -status Running  -PassThru)
}

ie assign the result of your call to the $ServiceInfo variable again.

Furthermore you should probably also create some kind of failsafe. Ie, if the service can't be started after for instance 5 iterations of your loop, print an error message and continue to the next machine. Otherwise, if there is some permanent issue with one of the machines, your loop will be stuck forever until you fix that issue.

And typically with this kind of operations, you use some kind of backoff strategy. Ie after the first failed attempt, apply some timeout, before trying again. And for every failed attempt extend that timeout.