PowerShell で .ps1 が実行できない(このシステムではスクリプトの実行が無効になっている)
Windows PowerShell 5.1 のクライアント既定は Restricted で、すべての .ps1 が実行できない。Set-ExecutionPolicy -Scope CurrentUser RemoteSigned で管理者権限なしに解除できる。
公開:
要約
.ps1 を実行しようとして次のエラーが出る場合、スクリプトの中身は一切関係ない。
PowerShell の実行ポリシーがスクリプトファイルの実行そのものを禁じている。
PS C:\work> .\setup.ps1
.\setup.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル
C:\work\setup.ps1 を読み込むことができません。
+ CategoryInfo : セキュリティ エラー: (: ) []、PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccessWindows クライアントに標準搭載される Windows PowerShell 5.1 の既定は Restricted で、公式ドキュメント(新しいタブで開く)にあるとおり「個別のコマンドは許可するが、スクリプトは許可しない」という設定である。
つまり初期状態の Windows では .ps1 は必ずこのエラーになる。
現在のユーザーだけを RemoteSigned に変えるのが定番の解決策で、管理者権限も要らない。
よくある原因
- 既定が
Restricted: Windows クライアントの既定値である。.ps1だけでなくモジュール(.psm1)やプロファイルも読み込まれない。
なお Windows Server の既定はRemoteSignedなので、サーバーでは動いたスクリプトが手元の PC で落ちる、という食い違いが起きる。 - 優先度の高いスコープが勝っている: 実行ポリシーは
MachinePolicy→UserPolicy→Process→LocalMachine→CurrentUserの順に評価される。
グループポリシーで配布されている環境では、Set-ExecutionPolicyが成功しても実効値が変わらない。 LocalMachineを権限なしで変更した: スコープを省略するとLocalMachineが対象になる。
管理者として実行していないと書き込みに失敗する。- ダウンロードしたファイルがブロックされている:
RemoteSignedはローカルで書いたスクリプトには署名を求めないが、インターネット由来のファイルには求める。
ブラウザやメールクライアントが付けた代替データストリームが残っていると、ポリシーを緩めても個別に弾かれる。
解決策
1. CurrentUser スコープで RemoteSigned にする
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSignedCurrentUser スコープなら管理者権限は不要で、変更は即時に有効になる。
PowerShell を再起動する必要もない。RemoteSigned は「ローカルで書いたスクリプトは署名なしで実行、ダウンロードしたものは署名必須」という設定で、Unrestricted や Bypass より安全側に倒せる。
2. どのスコープが勝っているか確認する
変更したのに実効値が変わらないときは、スコープごとの値を並べて見る。
Get-ExecutionPolicy -List Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser RemoteSigned
LocalMachine UndefinedMachinePolicy や UserPolicy に値が入っている場合はグループポリシーによる配布なので、PowerShell 側からは上書きできない。
管理者に相談するか、次の単発実行で回避する。
3. その場限りで実行する
ポリシーを恒久的に変えたくない、あるいは変えられない場合は、プロセススコープを使う。
powershell.exe -ExecutionPolicy Bypass -File .\setup.ps1この指定はレジストリではなく $Env:PSExecutionPolicyPreference に保存され、セッションを閉じると消える。
CI やインストーラーのようにその場だけ動かせばよい用途に向く。
4. ダウンロードした .ps1 のブロックを外す
Unblock-File .\setup.ps1ブロックされているかどうかは Get-Item .\setup.ps1 -Stream * で Zone.Identifier ストリームの有無として確認できる。
GitHub から ZIP で取得したスクリプト群がまとめて弾かれる場合は、展開先のフォルダに対して Get-ChildItem -Recurse | Unblock-File を流すとよい。