結論から先に書くと以下のコマンドをコマンドライン(あるいはパワーシェル)で入れればいいだけでした。
PS c:\> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
そもそも何が起きていたか
Windowsでnpmをインストールすると、npmコマンドの実体は実はPowerShellスクリプト(npm.ps1)として用意されています。つまり npm install と打つと、裏側では PowerShell がこのスクリプトファイルを実行しようとしています。
- PowerShellのデフォルトは「スクリプト実行禁止」
ここでポイントになるのが、PowerShellには**実行ポリシー(Execution Policy)**という安全装置があることです。
Windowsに元々入っているPowerShellでは、デフォルトの実行ポリシーが Restricted(制限あり)になっていることが多く、これは「どんな .ps1 スクリプトも実行させない」という設定です。
つまり npm 自体は正しくインストールされているのに、「npm.ps1というスクリプトを実行していいですか?」とPowerShellに聞かれ、「いいえ、絶対ダメです」と最初からブロックされている状態だったわけです。これが npm コマンドが使えなかった理由です。
なぜこんな厳しい設定になっているのか
これは「悪意のあるスクリプトを誤って実行してしまう」ことを防ぐためです。例えば怪しいメールの添付ファイルやダウンロードしたファイルに .ps1 スクリプトが紛れ込んでいて、それが意図せず実行されてシステムを壊されたり、情報を盗まれたりするのを防ぐ、いわば「デフォルトで鍵をかけておく」設計思想です。
コマンドの意味を分解する
powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
- Set-ExecutionPolicy:実行ポリシー(スクリプトを実行してよいかのルール)を変更するコマンド
RemoteSigned:「自分のPC内で作った/インストールしたスクリプトは実行OK。ただしインターネット経由でダウンロードしたスクリプトは、信頼できる発行元の署名がないと実行しない」という、程よい安全性を保ったポリシー - -Scope CurrentUser:この設定変更を「今使っているユーザーアカウントだけ」に適用する(PC全体・全ユーザーには影響させない)という指定
つまりこのコマンドは、「PCに元から入っているnpmのようなツールはちゃんと動かせるようにしつつ、それ以外の知らないスクリプトについては引き続き警戒する」という、バランスの取れた設定に変更している、というわけです。
補足:なぜmacOS/Linuxでは起きないのか
macOSやLinuxではnpmが .sh スクリプトやシェルコマンドとして動くため、Windowsのようなこの種の実行ポリシーの壁がなく、この問題は基本的に発生しません。Windows特有のPowerShellのセキュリティ機構によるものです。