主な使用コマンド一覧
実行中のサービス一覧を表示する
net start
全てのサービス一覧を表示する
sc query state=all
停止中のサービス一覧を表示する
sc query state=inactive
Windowsサーバーマネージャー上のサービス一覧を表示する
Powershell Get-service
テキスト文字列を検索する
findstr
netコマンドとscコマンドの違い
注意点としてはnetコマンドは同期、scコマンドは非同期であること。つまり、コマンドの終了を待たない処理(非同期)の場合はscコマンドで良いが、それ以外ではnetコマンドを使うべきである。
不具合を生む例として、net stop(停止) → net start(開始) この場合、サービスの終了を待たずにサービスを起動してしまうのでエラーとなる可能性がある。
その時はうまく動作しても不具合を生む可能性があるので基本的にはnet startコマンドで起動中のサービス一覧を取得、起動、停止することが好ましい。
起動判定のロジックについて
net start | findstr サービス名
起動中のサービス名を取得後にfindstrで文字列を検索する。コマンドが成功すればERRORLEVEL=0、失敗すればERRORLEVEL=1となる。これらを利用して判定を行います。
サービス起動判定のコード
net start | findstr サービス名
if %ERRORLEVEL%==0 (
net start サービス名
set STATUS=%ERRORLEVEL%
if %STATUS%==1 echo "error"
)
ロジックは問題ないのですが、これだと赤線の部分で不具合が発生します。
if文やfor文など()で囲んだ場合は環境変数の即時展開と言って、バッチファイルを読み込んだ時に展開されるという特性があるため注意が必要です。
つまり、()で囲んだ部分で宣言した環境変数は()で囲む前の環境変数を読み込むこととなりますので、set STATUS=%ERRORLEVEL%が宣言されていないのでエラーとなります。
対処方法
対処方法として環境変数の遅延展開を使用することで環境変数が実行時の値に書き換わるようにします。
先頭にsetlocal enabledelayedexpansion 末尾にendlocalを追加して %を!に変更します。
環境変数の遅延展開を使用することで、()内でSTATUSが宣言されて実行時に%ERRORLEVEL%が代入されます。
rem 遅延展開開始
setlocal enabledelayedexpansion
rem 起動:0 停止:1
net start | findstr サービス名
if %ERRORLEVEL%==0 (
rem 起動:1 停止:0
net start サービス名
set STATUS=!ERRORLEVEL!
if !STATUS! neq 0 echo "error"
)
rem 遅延展開終了
endlocal
環境変数の遅延展開を利用することで無事サービス起動時のエラー判定ができました!