npmから学ぶ実行ポリシー

Date2026/08/24 Last Modified2026/08/24

概要

「管理者権限が無くてnpmコマンドが実行できない!」
これは会社PCを与えられてから、ずっと悩まされてきた問題。しかしnpm.cmdを利用すれば問題ないということを知ってからは、ちょっと打つ文字が多いな……というくらいであんまり気にせずにいた。
実際、あんまり管理者権限がどういうものなのか詳しく理解しておらず、気まぐれで現れては妨害してくるめんどくさい奴、くらいに思っていた。
しかし今回、なぜかふと気になってしまい詳しく調べたところ、すべての謎が解けた。

そもそも管理者権限とは

Windowsを使っているとあんまり意識することはないが、Linuxでいうとrootみたいなもの。
なので、ユーザーグループや実行権限にさえ注目すれば「気まぐれなやつ」ではなく、「規則に従って制限を加えてくるやつ」である。

そして基本的にして結論となるのは「OSのユーザー全員に作用することは制限されている」ということ。
なので、グローバル領域であるC:\Program FilesC:\Windows\System32などはローカルユーザーでは編集できないのである。

例えば、こんな実験方法がある。

$paths = @(
>>     $env:USERPROFILE,
>>     $env:LOCALAPPDATA,
>>     $env:TEMP,
>>     $env:ProgramFiles,
>>     $env:ProgramData,
>>     "$env:SystemRoot\System32"
>> ) 
>> foreach ($path in $paths) {
>>     $testFile = Join-Path $path (".__permission_test_" + [guid]::NewGuid() + ".tmp")
>>
>>     try {
>>         New-Item $testFile -ItemType File -ErrorAction Stop | Out-Null
>>         Remove-Item $testFile -ErrorAction SilentlyContinue
>>         Write-Host "[WRITE OK] $path"
>>     }
>>     catch {
>>         Write-Host "[DENIED]   $path"
>>     }
>> }

これで、どこに書き込み権限があるのかをはっきりと知ることができたりする。

今回の主題はnpmコマンドなので、実行権限を知りたいのであればまずは場所をみるべし。

‘C:\Users\UserHoge\apps\nodejs\npm.ps1’ あれ、ローカルにあるから実行できるはずだぞ……。と気付く。
ここで実行ポリシーという難題に突き当たった。

実際のエラー本文

npm : ファイル C:\Users\UserHoge\apps\nodejs\npm.ps1 を読み込めません。ファイル C:\Users\UserHoge\apps\nodejs\npm.ps1 は
デジタル署名されていません。このスクリプトは現在のシステムでは実行できません。スクリプトの実行および実行ポリシーの設定
の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1

実行ポリシーとデジタル署名

エラー本文をよく読んでみると、実行ポリシーとデジタル署名とある。
これ実は、管理者権限とはまた別の領域にあるもの。
なぜ領域が分かれているかといえば、管理者であっても「危険なファイルを実行してるけど大丈夫?」とWindowsが警告を出す必要があるから。

さて、まず実行ポリシーとは何かというと、そのアプリケーションで実行することができるファイルの状態を分けるものである。

Restricted    → 原則スクリプト禁止
AllSigned     → 全部署名必要
RemoteSigned  → 外部由来だけ署名必要
Unrestricted  → 基本許可。ただし外部由来で警告することがある
Bypass        → チェックも警告もほぼなし
Undefined     → 「この階層では設定してません」

確認してみると、実行環境であるPowershellはRemoteSignedになっていた。
これを詳しく紐解くと、

実行ポリシーを満たすには、署名済み、もしくは許可されたファイルである

  • 許可されたファイルであるとは? Windowsのファイルシステム(NTFS)では、Zone.Identifierというストリームが存在し、そこでどんな経路で取得したかが記録されるようになっている。
    そこで外部(インターネット)から取得したという情報が書いており、この状態だと許可されたファイルではないという判定になる。
    もしこのZone.identifierを削除すれば許可されたファイルとなる。その方法は、Unblockコマンドを実行すること。

  • 署名済みであるとは? その実行ファイルの作成者に署名がついている(証明書が付与されている)かどうかの判定。
    ただし、その証明書は自分で勝手に発行して付ければよいというわけではなく「信頼されたルート証明機関」によってRoot CAが登録されているかが重要。(社内用に発行するとかはまた別)
    そしてWindowsのホワイトリストにあたるもの(Trusted Root Certification Authorities)に、そのルート証明機関が登録されていれば、初めて署名済みになる。

これらを総合してみると……
実行ポリシーを達成する方法は「Unblockコマンドを実行すること!」
これでZone.Inentifierを削除して一件落着である。

完全に理解したとしても、思い込みはいけない

Unblock-File -LiteralPath 'C:\Users\UserHoge\apps\nodejs\npm.ps1'
Unblock-File -LiteralPath 'C:\Users\UserHoge\apps\nodejs\npx.ps1'

このコマンドを実行するだけで、長いこと悩まされてきたnpmの実行ポリシー問題は終結……。
これまではわかったような気になって「管理者権限がないからnpmもあれもこれもできないんですよね」と言いふらしていたが、さすがに反省。

また一つ賢くなったが、OSの世界はさらに奥が深い。
今回のこと1つとっても、まだ表層の理解しかしてないことがわかったのでもっと色々知ってみたいと思った。