TL;DR
ターミナルを右クリック → 管理者として実行。それでも弾かれる場合は、対象ファイルまたはフォルダの所有権を取得してください:
takeown /f "C:\path\to\file" /r /d y
icacls "C:\path\to\file" /grant %USERNAME%:F /t
これで9割のケースは解決します。解決しない場合は続きを読んでください。
なぜこのエラーが発生するのか
WindowsのAccess is deniedはパスワードが間違っているという意味ではありません。OSレベルの権限チェックが失敗したという意味です。原因は大きく5つあり、それぞれ異なる修正が必要です:
- 昇格されていない実行 — アカウントが管理者グループに属していても、ターミナルが管理者権限なしで開かれている。
- UACのトークン分割 — Windowsはデフォルトで管理者アカウントを制限付きトークンで実行します。フルの管理者権限を得るにはプロセスの明示的な昇格が必要です。
- ファイルの所有権がない — システムファイル、別ユーザーが作成したファイル、または
TrustedInstallerが所有するファイルは、管理者でも書き込みがブロックされます。 - ACLで明示的に拒否されている — 拒否のACEは管理者グループのメンバーシップを含むすべての許可ルールより優先されます。多くの人がここで躓きます。
- ファイルがロックされている — 別のプロセスが排他ロックを保持しています。権限チェックは通過しますが、ファイルシステム層でI/Oがブロックされます。
修正1:CMDまたはPowerShellを管理者として実行する
熟練したシステム管理者でも頻繁に遭遇する問題です。Administratorsグループに属していても、自動的に昇格された権限が付与されるわけではありません——シェルが明示的にそれを要求する必要があります。
- Winキーを押して
cmdまたはpowershellと入力し、右クリック → 管理者として実行。 - または既存のターミナルから:
Start-Process powershell -Verb RunAs
昇格が成功したか確認します——タイトルバーに管理者: コマンド プロンプトと表示されるはずです。以下のコマンドでも確認できます:
whoami /groups | findstr "S-1-16-12288"
この行が表示されれば、高整合性(昇格済み)トークンを持っています。出力がなければまだ制限付きで実行されています。
修正2:ファイルまたはフォルダの所有権を取得する
システムファイルやWindows Updateの成果物は通常、SYSTEMまたはTrustedInstallerが所有しています。昇格済みの管理者でも、先に所有権を取得しないと書き込みができません——これは意図的な仕様です。
昇格済みのCMDから:
takeown /f "C:\path\to\target" /r /d y
次にフルコントロールを自分に付与します:
icacls "C:\path\to\target" /grant %USERNAME%:F /t /c
フラグの説明:/t = 再帰的、/c = エラー時も継続、F = フルコントロール。
単一のシステムファイル(例:DLLの置き換え)の場合:
takeown /f "C:\Windows\System32\somefile.dll"
icacls "C:\Windows\System32\somefile.dll" /grant Administrators:F
**確認:**元の失敗したコマンドを再実行します。現在の権限は以下で確認できます:
icacls "C:\path\to\target"
修正3:PowerShellで明示的な拒否ACEを削除する
ACLの拒否エントリは管理者権限を含むすべてをオーバーライドします。その上に許可ルールを追加するだけでは解決しません。拒否エントリ自体を削除する必要があります。
まず、ACLの実際の内容を確認します:
$acl = Get-Acl "C:\path\to\target"
$acl.Access | Format-Table IdentityReference, FileSystemRights, AccessControlType
自分のアカウントまたはUsersに対するDenyエントリを見つけたら削除します:
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"BUILTIN\Users", "FullControl", "Deny"
)
$acl.RemoveAccessRule($rule)
Set-Acl "C:\path\to\target" $acl
BUILTIN\UsersとFullControlは、拒否エントリに実際に表示されている値に置き換えてください。
修正4:別プロセスが保持するファイルロックを解除する
権限は問題ないのにまだブロックされている場合、原因はファイルのロックであることがほとんどです。別のプロセスが排他ロックでファイルを開いており、そのプロセスが解放するまでWindowsはアクセスを許可しません。
Sysinternalsのhandle.exeでロックしているプロセスを特定します:
# Sysinternalsのhandle.exeがPATHにある場合:
handle.exe "C:\path\to\file"
Sysinternalsがない場合はリソース モニターを使用します:Win+Rを押してresmonと入力 → CPUタブ → 関連ハンドル → ファイル名で検索。
ロックしているプロセスを閉じるか終了させてから、コマンドを再試行します。
修正5:レジストリキーへのアクセス拒否
HKLM配下のレジストリエラーは別の問題です。昇格だけでは不十分で、HKLM\SAMやHKLM\SECURITYのような保護されたキーは、ファイルと同様に先に所有権を取得する必要があります。
# 現在の所有者を確認
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
"SOFTWARE\SomeKey", $true
)
# エラーが発生する場合:regeditで所有権を取得
# キーを右クリック → アクセス許可 → 詳細設定 → 所有者 → 自分のアカウントに変更
スクリプトでの書き込みを素早く行うには、PowerShell APIを使わず昇格済みプロンプトからreg addを使う方が簡単です:
reg add "HKLM\SOFTWARE\SomeKey" /v ValueName /t REG_SZ /d "data" /f
修正6:スケジュールタスクとサービス
スケジューラとサービスのエラーは別の問題です。通常、あなた自身の権限ではなく、タスクを実行しているサービスアカウントにアクセス先リソースへの権限がないことが原因です。
サービスをLocalSystem(広範なアクセス権)で実行するか、特定のユーザーに紐付けます:
sc.exe config ServiceName obj= "LocalSystem" password= ""
# または特定のアカウントの場合:
sc.exe config ServiceName obj= ".\YourUsername" password= "yourpassword"
変更を適用するために再起動します:
net stop ServiceName && net start ServiceName
診断チェックリスト
- ターミナルは昇格されているか?(
whoami /groups | findstr S-1-16-12288) - ファイルの所有者は誰か?(
icacls "path"— 所有者の行を確認) - 明示的な拒否ACEはあるか?(icaclsの出力に
(DENY)がないか確認) - ファイルはロックされているか?(リソース モニター → 関連ハンドル)
- システム保護パスか?(例:
C:\Windows\System32)
補足Tips
WSLやクロスプラットフォームデプロイなど、WindowsとLinuxを同時に扱っている場合、ToolCraftのUnix権限計算ツールを使えばchmodの値を視覚的に確認してから適用できます。Windows側で設定している内容に合わせてLinuxのファイル権限を調整する際に便利です。
予防策
- 昇格が必要なスクリプトは専用フォルダに入れ、明確なREADMEを用意しておくと「またなんで失敗してるんだ」というループを防げます。
- 一時的な昇格コマンドには
runas /user:Administrator cmdを使うと、手動で新しいウィンドウを開かずに済みます。 - WindowsのCI/CDパイプラインでは、エージェントのサービスアカウントを常に明示し、初回実行前にicaclsで作業ディレクトリへの権限を付与しておきましょう。

