できない.dev

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 : UnauthorizedAccess

Windows クライアントに標準搭載される Windows PowerShell 5.1 の既定は Restricted で、公式ドキュメント(新しいタブで開く)にあるとおり「個別のコマンドは許可するが、スクリプトは許可しない」という設定である。
つまり初期状態の Windows では .ps1 は必ずこのエラーになる。

現在のユーザーだけを RemoteSigned に変えるのが定番の解決策で、管理者権限も要らない。

よくある原因

  1. 既定が Restricted: Windows クライアントの既定値である。.ps1 だけでなくモジュール(.psm1)やプロファイルも読み込まれない。
    なお Windows Server の既定は RemoteSigned なので、サーバーでは動いたスクリプトが手元の PC で落ちる、という食い違いが起きる。
  2. 優先度の高いスコープが勝っている: 実行ポリシーは MachinePolicyUserPolicyProcessLocalMachineCurrentUser の順に評価される。
    グループポリシーで配布されている環境では、Set-ExecutionPolicy が成功しても実効値が変わらない。
  3. LocalMachine を権限なしで変更した: スコープを省略すると LocalMachine が対象になる。
    管理者として実行していないと書き込みに失敗する。
  4. ダウンロードしたファイルがブロックされている: RemoteSigned はローカルで書いたスクリプトには署名を求めないが、インターネット由来のファイルには求める。
    ブラウザやメールクライアントが付けた代替データストリームが残っていると、ポリシーを緩めても個別に弾かれる。

解決策

1. CurrentUser スコープで RemoteSigned にする

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

CurrentUser スコープなら管理者権限は不要で、変更は即時に有効になる。
PowerShell を再起動する必要もない。RemoteSigned は「ローカルで書いたスクリプトは署名なしで実行、ダウンロードしたものは署名必須」という設定で、UnrestrictedBypass より安全側に倒せる。

2. どのスコープが勝っているか確認する

変更したのに実効値が変わらないときは、スコープごとの値を並べて見る。

Get-ExecutionPolicy -List
        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       Undefined

MachinePolicyUserPolicy に値が入っている場合はグループポリシーによる配布なので、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 を流すとよい。

この記事は役立ちましたか?