PowerShell Start-Service Runs Endlessly

Viewed 4355

Problem

So I have a block of code meant to start a service and have the service time out if it takes too long and works fine for the most part. Unfortunately, when this service attempts to start a service that cannot be started, it will display the following Warning Message:

WARNING: Waiting for 'ServiceName <ServiceName>' to start...

This message will display once every 1-2 seconds, but the time-out never occurs and the Start-Service action seems to continue endlessly. I can safely verify that it will at least continue for 30 minutes (before I manually killed the action).

The code is as follows:

Start-Service $ServiceName -ErrorAction SilentlyContinue
$results = Wait-ServiceState -ServiceName $ServiceName -ServiceState 'Running' -SecondsToWait $SecondsToWait

Function Wait-ServiceState {
    Param (...)
    Process {
        Try {
            $check = Get-Service $ServiceName
            $timeout = New-TimeSpan -Seconds $SecondsToWait

            $check.WaitForStatus($ServiceState, $timeout.ToString())

            If ($check.Status -ne $ServiceState) { return $False }
            Else { return $true }
        }
        Catch {
            # do nothing: handled by an upper level function
        }
    }
}

I have tested the above function against a couple other services and it appears to work fine. I have also successfully used it with Stop-Service with absolutely zero issues. I have been searching through threads all morning and have not been able to find anything even remotely similar. I do not know what I am missing...

Question

Does anyone have an idea on why it isn't timing out like its supposed to? Perhaps even know how to resolve this?

2 Answers

Shout out to @BaconBits for his suggestion:

By converting the following line:

Start-Service $ServiceName -ErrorAction SilentlyContinue

To:

$s = Get-Service $ServiceName
$s.Start()

The application stops hanging on the Start-Service line and successfully advances to the WaitForStatus line and everything processes the way I expect it to, regardless of whether the start is successful or not.

However, it seems that the use of one over the other vastly depends on whether you are running in Administrative mode or not.

Here's one way to start a service and wait for a specified amount of time for it to start. It returns 0 if the service started successfully, or an error code if 1) the service doesn't exist, 2) the service is already running, or 3) the code timed out waiting for the service to start.

$ERROR_SERVICE_REQUEST_TIMEOUT = 1053
$ERROR_SERVICE_ALREADY_RUNNING = 1056
$ERROR_SERVICE_DOES_NOT_EXIST  = 1060

function Start-Service {
  param(
    [String] $serviceName,
    [Int32] $timeoutSeconds
  )
  $service = Get-Service $serviceName
  if ( -not $service ) {
    return $ERROR_SERVICE_DOES_NOT_EXIST
  }
  if ( $service.Status -eq [ServiceProcess.ServiceControllerStatus]::Running ) {
    return $ERROR_SERVICE_ALREADY_RUNNING
  }
  $timeSpan = New-Object Timespan 0,0,$timeoutSeconds
  try {
    $service.Start()
    $service.WaitForStatus([ServiceProcess.ServiceControllerStatus]::Running, $timeSpan)
    return 0
  }
  catch [Management.Automation.MethodInvocationException],[ServiceProcess.TimeoutException] {
    return $ERROR_SERVICE_REQUEST_TIMEOUT
  }
}
Related