Windows: net と sc どちらでサービスをコントロールするか

Windows OS にてオフラインバックアップを取得する為にサービスを停止・起動する為のスクリプトを書く事があります。どこかのサーバで一括して処理を行う事を前提に考えると、コンピュータ名を明示できる sc を使う事になりますが、単体構成のサーバ上でコントロールをする場合はどちらが良いのか考えどころです。

そこで簡単に2つのコマンドの機能を色々と調べてみましたが、次のような差異がありました。

  1. 引数とするサービスの名前の違い
  2. 同期・非同期の違い

引数とするサービスの名前の違いについてですが、 net はサービス一覧に出力されるサービス名をそのまま指定すればOKのようです。一方で sc は表示名ではコントロールできず ServiceKeyName にてコントロールする必要があるという事。したがって、例えば “Virtual Disk” サービスを止めようとした場合には次のような差異が出ます。

C:Usershoge>net stop "Virtual Disk"
Virtual Disk サービスを停止中です.
Virtual Disk サービスは正常に停止されました。

net コマンドなのでサービス名でそのまま止まりました。

C:Usershoge>sc stop "Virtual Disk"
[SC] OpenService FAILED 1060:

指定されたサービスはインストールされたサービスとして存在しません。

サービス名を指定したら「そんなサービスはインストールされていない」と怒られました。そこで ServiceKeyName を調べます。

C:Usershoge>sc GetKeyName "Virtual Disk"
[SC] GetServiceKeyName SUCCESS
名前 = vds

ServiceKeyName は vds である事が判ったので改めてコマンドを発行してみます。

C:Usershoge>sc stop vds

SERVICE_NAME: vds
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

止まりました。

ここまで確認すると ServiceKeyName にはスペースが入らないようなのでスクリプトから読み出したりする場合には何となく sc の方が良いような気がします。ところがもう一方の同期・非同期の方が結構な問題です。

サービス制御は Service Control Manager が代理で実行するので、sc stopは「終わらせて」と言ったきりで完全には終わり
を待たない可能性は高いですね。

上記のようなコメントがフォーラム上に掲載されていました。事実関係まで突き止めていないのですが、もしも事実であれば無闇に sc でコントロールするのは少々怖いですね。

とりあえず複数台のサーバをコントロールしなければならない場合には sc 。単体サーバ上でのコントロールであれば net を使うというのが落としどころに思えます。

via
サービスを開始、停止、一時停止、再開、または再起動する (Microsoft technet)
scコマンドは同期?非同期? (MSDNフォーラム)