17

stop-service コマンドレットを使用して、ボックスのいくつかのサービスを強制終了しています。ほとんどの場合は問題なく動作しますが、時々うまく動作しないサービスが 1 つまたは 2 つあります (そうでない人はいますか?)。

この場合、問題のサービスの 1 つが停止状態のままになり、コマンドレットはこれをコンソールに何度も出力します。

[08:49:21]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish 
[08:49:21]stopping...
[08:49:23]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish 
[08:49:23]stopping... 
[08:49:25]WARNING: Waiting for service 'MisbehavingService (MisbehavingService)' to finish 
[08:49:25]stopping...

最終的には、タスク マネージャーでサービスを強制終了する必要があり、その後スクリプトが続行されます。

stop-service コマンドレットを特定の時点で停止またはタイムアウトさせる方法はありますか? 後で確認できると思いますが、サービスがまだ実行されている場合は、kill-process コマンドレットを使用して最後のチョップを提供します。

4

3 に答える 3

19

にはStop-Serviceタイムアウト パラメーターはありませんが、クラスのWaitForStatusメソッドにはタイムアウト パラメーターを受け取るオーバーロードがあります (ドキュメントはこちら)。幸いなことに、これはまさにコマンドが返すオブジェクトのタイプです。System.ServiceControllerGet-Service

以下は、サービス名と秒単位のタイムアウトを取る単純な関数です。$trueタイムアウトに達する前にサービスが停止した$false場合、および呼び出しがタイムアウトした場合 (またはサービスが存在しない場合)に戻ります。

function Stop-ServiceWithTimeout ([string] $name, [int] $timeoutSeconds) {
    $timespan = New-Object -TypeName System.Timespan -ArgumentList 0,0,$timeoutSeconds
    $svc = Get-Service -Name $name
    if ($svc -eq $null) { return $false }
    if ($svc.Status -eq [ServiceProcess.ServiceControllerStatus]::Stopped) { return $true }
    $svc.Stop()
    try {
        $svc.WaitForStatus([ServiceProcess.ServiceControllerStatus]::Stopped, $timespan)
    }
    catch [ServiceProcess.TimeoutException] {
        Write-Verbose "Timeout stopping service $($svc.Name)"
        return $false
    }
    return $true
}
于 2016-03-08T15:44:33.773 に答える
7

stop-service にはタイムアウト オプションはありませんが、依存するサービスがある場合は、-force を使用する必要がある場合があります。

サービスは開始時に (タイムアウトを指定する) 待機ヒントを定義できますが、タイムアウトはサービスによって制御されます。すべてのサービス コントロール要求 (開始、停止、一時停止、再開) は、サービス コントロール マネージャー (SCM) を通過し、各サービスの待機ヒントに従います。待機ヒントを超えると、操作は失敗し、エラーが返されます。

invoke-command を使用して Stop-Service をジョブとして実行し、定期的にチェックすることができます。完了していない場合は、Stop-Process を使用してプロセスを強制終了し、続行できます。

于 2012-09-21T16:33:09.250 に答える