シナリオ
午前2時。Windowsサーバー上でサービスがクラッシュしました。CMDを開き、いつものコマンドを入力します:
net stop MyService
net start MyService
すると、こんなエラーが表示されます:
System error 5 has occurred.
Access is denied.
あるいは sc を試したかもしれません:
sc stop MyService
[SC] OpenService FAILED 5:
Access is denied.
同じ壁にぶつかります。サービスはまだ停止中、インシデントはまだオープン、時間はどんどん過ぎていきます。
なぜこのエラーが発生するのか
エラー5は、サービスコントロールマネージャー(SCM)を呼び出しているプロセスに十分な権限がないことを示すWindowsのメッセージです。これを引き起こす原因は2つあります:
- CMDを通常ユーザーとして実行している — アカウントがAdministratorsグループに属していても、UACはデフォルトで管理者トークンを剥奪します。明示的に昇格させるまで、実質的には標準ユーザーとして扱われます。
- サービスに厳しい権限が設定されている — 一部のサービス(アンチウイルス、EDRエージェント、Windows Defenderなど)は、SYSTEMまたは特定のサービスアカウント以外のすべてのユーザーに対して、起動・停止を明示的にブロックしています。
10回中9回は最初のケースです。スタートメニューやデスクトップのショートカットからCMDを開いており、右クリックによる昇格を行っていないのが原因です。
クイックフィックス:昇格したCMD
90%のケースはこれで解決します。約10秒で完了します。
方法1 — 右クリックで昇格
Winキーを押してcmdと入力- コマンドプロンプト を右クリック → 管理者として実行
- UACプロンプトを承認
- コマンドを再試行:
net stop MyService
net start MyService
タイトルバーに「Administrator: Command Prompt」と表示されていれば、昇格していることの確認です。
方法2 — PowerShellワンライナー(GUIなし)
昇格していないターミナルに既にいる場合は、そこから昇格したCMDを起動できます:
Start-Process cmd -Verb RunAs -ArgumentList '/k sc stop MyService'
一度の操作で停止と再起動を行うには:
Start-Process cmd -Verb RunAs -ArgumentList '/k net stop MyService && net start MyService'
方法3 — ネイティブPowerShellコマンドレット
Stop-Service -Name "MyService" -Force
Start-Service -Name "MyService"
Stop-Service と Start-Service は内部的に同じSCMを使用しています。利点は、エラーメッセージが不可解な終了コードではなく、人間が読みやすい形式で表示されることです。
修正が成功したか確認する
sc query MyService
出力に STATE : 4 RUNNING が表示されているか確認してください。PowerShellを使いたい場合は、代わりにこちらを実行してください:
Get-Service -Name "MyService" | Select-Object Name, Status
期待される出力:
Name Status
---- ------
MyService Running
管理者として実行してもまだエラー5が出る場合
タイトルバーに「Administrator: Command Prompt」と表示されているか再確認してください。表示されているにもかかわらずエラー5が続く場合、サービス自体に制限的なセキュリティ記述子が設定されており、管理者トークンでも不十分です。
現在のサービス権限を確認する
sc sdshow MyService
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)... のような生のSDDL文字列が返されます。確認すべき点は2つ:RP(起動権限)と WP(停止権限)です。BA(Built-in Administrators)の隣にどちらも表示されていない場合、それが問題です。
Administratorsにサービスのフルコントロールを付与する
sc sdset を使って記述子を上書きします。これはAdministratorsに対する標準的なフルコントロールSDDLで、ほとんどの非クリティカルなサービスに対して安全に使用できます:
sc sdset MyService "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)"
主要なトークンの意味:
BA— Built-in Administrators(組み込み管理者)CCDCLCSWRPWPDTLOCRSDRCWDWO— フルコントロール:起動、停止、一時停止、設定変更、削除SY— ローカルシステムアカウントIU/SU— インタラクティブユーザーとサービスユーザー(読み取り専用アクセス)
実行後、net stop MyService を再試行してください。問題なく通るはずです。
恒久的な解決策:同じ問題を繰り返さないために
デプロイメントスクリプトや自動化処理でこのエラーが繰り返し発生する場合、本当の解決策は昇格処理をスクリプト自体に組み込むことです。毎回右クリックを覚えておく必要はありません。
スケジュールタスクの場合
タスクスケジューラを開き、該当タスクを見つけてから:
- 右クリック → プロパティ
- 最上位の特権で実行する にチェックを入れる
- 「セキュリティオプション」で、アカウントが管理者であることを確認
デプロイメントスクリプト(バッチファイル)の場合
.bat ファイルの先頭にこの自動昇格ブロックを追加してください。昇格していない場合は、管理者権限で自分自身を再起動します:
@echo off
net session >nul 2>&1
if %errorlevel% neq 0 (
echo Requesting admin privileges...
powershell -Command "Start-Process '%~f0' -Verb RunAs"
exit /b
)
net stop MyService
net start MyService
PowerShellスクリプトの場合
#Requires -RunAsAdministrator
Restart-Service -Name "MyService" -Force
Write-Host "Service restarted successfully."
#Requires -RunAsAdministrator ディレクティブは、使われていないにもかかわらず非常に便利です。昇格していない場合、PowerShellはスクリプトの実行を一切拒否します。実行途中で紛らわしいアクセス拒否エラーが出る代わりに、冒頭で明確な「管理者として実行する必要があります」というメッセージが表示されます。
リモートサービス:別の問題
sc \\servername を使って別のマシンのサービスを管理しようとしてもエラー5が出る場合、ローカルの昇格では不十分です。
sc \\remoteserver query MyService
[SC] OpenSCManager FAILED 5:
Access is denied.
リモートアクセスを修正する3つの方法:
- リモートマシンのローカルAdministratorsグループにドメインアカウントを追加する(最も確実)
runas /user:remoteserver\Administrator sc \\remoteserver stop MyServiceを使って明示的な認証情報を提供する- 認証情報をよりクリーンに扱うためにPowerShellリモーティングを使用する:
Invoke-Command -ComputerName remoteserver -ScriptBlock { Restart-Service MyService } -Credential (Get-Credential)
まとめ
- 90%のケース:CMDを管理者として再起動し、コマンドを再試行する
sc query MyServiceで確認 →STATE : 4 RUNNINGを探す- 昇格しても失敗する場合:
sc sdsetでサービスのDACLを修正する - 自動化:バッチファイルに自動昇格を追加するか、PowerShellスクリプトに
#Requires -RunAsAdministratorを追加する - リモートマシン:自分のマシンだけでなく、対象マシンのローカルAdminsにアカウントが含まれている必要がある

