PowerShell: Restart a Service on All Hyper-V Hosts of a Cluster

$serviceName='vmms'
$clusterName='HyperV-cluster001'

function restartServiceAllClusterNodes($service='vmms',$clusterName){
  function restartService($serviceName){
    $waitSeconds=40
    $isValidProcess=try{[bool](get-service $serviceName -EA Stop)}catch{$false}
    if($isValidProcess){
        try{
            $process=Start-Process -FilePath powershell.exe -ArgumentList "-Command Restart-Service $serviceName" -PassThru -NoNewWindow
            $process|Wait-Process -Timeout $waitSeconds -ErrorAction Stop
            return $true
        }catch{
            write-warning $_
            $process|Stop-Process -Force
            $processId=(get-process $serviceName).Id
            if($processId){
                write-host "Program now forcefully kills PID $processId of process $serviceName"
                $null=$processId|%{taskkill /f /pid $_} # works more reliably than Stop-Process $processName -Force
                Start-Service $serviceName -ErrorAction Ignore
                $started=$(try{get-service $serviceName}catch{$false})
                if($started){
                    write-host "'serviceName' status is now $($started.Status)"
                    return $true
                }else{
                    write-warning "'serviceName' status is $($started.Status)"
                    return $false
                }
            }else{
                write-warning "Service '$serviceName' PID not found."
                return $false        
            }
        }
    }
  }

  $results=@()
  try{
    Import-Module FailoverClusters
    $clusterName=if($clusterName){
      invoke-command -computername $clustername {(get-cluster).name}
    }else{
      (get-cluster).name
    }
    $allHyperVHosts={(Get-ClusterNode -Cluster $clusterName|?{ $_.State -eq "Up" }).Name | %{$_.ToLower()}}.Invoke()
    foreach ($hyperVHost in $allHyperVHosts){
      $result=invoke-command -computername $hyperVHost -EA SilentlyContinue -scriptblock {
        param($restartService,$serviceName)
        [scriptblock]::create($restartService).invoke($servicename)
      } -Args ${function:restartService},$serviceName
      write-host "$hypervHost=$result"
      $results+=[pscustomobject]@{$hypervHost=$result}
    }
  }catch{
    write-warning $_    
  }
}

$results=restartServiceAllClusterNodes $serviceName $clusterName
$results

Leave a Reply

Your email address will not be published. Required fields are marked *