おれさまラボ

実際に手を動かして理解を深めるブログ。

PowerShell の実行ポリシー

はじめに

いつもわからなくなるのでメモしておきます。

実行ポリシーとは

実行ポリシーとは「PowerShell が構成ファイルを読み込み、スクリプトを実行する条件を制御する安全機能」1のことです。この機能があることで、意図しない悪意のあるスクリプトの実行を防ぐことができます。

実行ポリシーの設定値

実行ポリシーには5つの設定値が用意されています。ちなみに restrict は「制限する」、 sign は「署名する」という意味の英単語です。

設定値
コマンドの実行
ローカル スクリプトの実行
インターネット由来のスクリプトの実行
備考
署名あり
署名なし
署名あり
署名なし
Restricted
個々のコマンド実行はできるが、スクリプト実行はできない。
AllSigned
署名付きスクリプトであれば実行できる。
RemoteSigned
インターネット由来のスクリプトは署名付きである必要がある。
Unrestricted
すべてのスクリプト実行ができるが、警告は表示される。
Bypass
ブロックも警告の表示もなし。通常使うべきではない。

上記設定値以外に Undefined という値を持ちえますが、これは実行ポリシーが何も設定されていない状態にあるということを意味します。Undefined の状態は Default と同義であり、Restricted 状態となります。

署名付きスクリプト

PowerShell スクリプトファイルに対して、電子署名を付加することができます。電子署名が付与された PowerShell スクリプトのことを「署名付きスクリプト」と言います。電子署名が付加されていることで、「誰がこのソフトウェアに責務をもっているのか」「配布してからソフトウェアが改変されていないか」が明らかになります。実行ポリシーの AllSignedRemoteSigned は、この電子署名が行われているかを条件とする実行ポリシーです。

参考:PowerShell 実行ポリシー | Microsoft Docs

実行ポリシーのスコープ

PowerShell には実行ポリシーのスコープという概念があります。スコープによって、実行ポリシーの適用範囲が決まります。

スコープ 影響範囲 管理者昇格 適用期間 設定格納場所
Process 現在の PowerShell プロセスのみ 不要 現在の PowerShell セッションのみ 環境変数
CurrentUser 現在のユーザーのみ 不要 永続 HKEY_CURRENT_USER レジストリサブキー
LocalMachine コンピューターのすべてのユーザー 必要 永続 HKEY_LOCAL_MACHINE レジストリサブキー

Process スコープの挙動

Process スコープは、他のスコープよりも優先されます。もし、Process スコープで Unristricted であれば、スクリプトは無制限に実行できます。

この他に MachinePolicyUserPolicy というスコープがありますが、これらはグループポリシーで指定される値です。

どの実行ポリシーを使うべき?

  • よくあるケースとしては、管理者権限が剥奪されているが、グループポリシーで PowerShell の実行ポリシーまでは制限されていないという状態でしょう。この場合、まずは Process スコープの実行ポリシーのみを RemoteSigned とするのが良いでしょう。CurrentUserLocalMachine の実行ポリシーが Restricted になっていたとしても、現在の PowerShell セッション内であればスクリプトを実行することができます。

  • 逆に、一度 PowerShell を閉じてしまうと Process スコープの設定値は Undefined(=DefaultRestricted)に戻ってしまうので、スクリプト実行頻度が高く煩わしい場合には CurrentUser スコープを RemoteSigned とするのが良いでしょう。こうすることで、PowerShell を閉じたり、PC を再起動したとしても、CurrentUser の設定値が元に戻ってしまうことはありません。

  • インターネットから取得したスクリプトを直接使用する場合には、PowerShell プロセス生成時に実行ポリシーを Unrestricted とすると良いでしょう。インターネット上に公開されたスクリプトは便利ですが、悪意のあるコマンドが含まれていないとは限りません。スクリプトの内容は精査した上で、実行するように心がけましょう。

  • なお、管理者権限でスクリプトを実行する場合は、実行ポリシーが Restricted となっている場合でも実行できてしまうことは覚えておきましょう。

実行ポリシーの確認

実行ポリシーは Get-ExecutionPolicy コマンドレットを使用することで確認できます。

> Get-ExecutionPolicy
Restricted

なお、Windows 10 PC では、各スコープに対してのデフォルト値は以下の通り設定されていない状態です。この default 値状態だと、実行ポリシーは Restricted と同義となります。

> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

実行ポリシーの設定

実行ポリシーの設定方法は3つあります。

スクリプト実行時に実行ポリシーを指定する

PowerShell プロセス生成時に実行ポリシーを指定することができます。設定値は当該のプロセスのみで有効で、永続化されません。

> powershell -ExecutionPolicy Unrestricted -File .\Test-Script.ps1

不適切な実行ポリシーを指定すると、以下のようにエラーとなります。

powershell -ExecutionPolicy AllSigned -File .\Test-Script.ps1
. : ファイル C:\Users\User\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 を読み込めません。ファイル
C:\Users\User\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 はデジタル署名されていません。このスクリ
プトは現在のシステムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Pol
icies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:3
+ . 'C:\Users\User\Documents\WindowsPowerShell\Microsoft.PowerShell ...
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
ファイル C:\Users\User\Downloads\Test-Script.ps1 を読み込めません。ファイル C:\Users\User\Downloads\Test-Script
.ps1 はデジタル署名されていません。このスクリプトは現在のシステムでは実行できません。スクリプトの実行および実行ポリシー
の設定の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください

    + CategoryInfo          : セキュリティ エラー: (: ) []、ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

Set-ExecutionPolicy コマンドレットを使用する

Set-ExecutionPolicy コマンドレットを使用することで、設定を永続化することができます。

引数に実行ポリシーのみを持たせると、LocalMachine の設定が変更されます。

> Set-ExecutionPolicy Unrestricted
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine    Unrestricted

スコープを明示的に指定することで、当該スコープのみを変更できます。

> Set-ExecutionPolicy -Scope CurrentUser Unrestricted
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    Unrestricted
 LocalMachine       Undefined

デフォルト値に戻したい場合は、Default を指定します。

> Set-ExecutionPolicy -Scope CurrentUser Default
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser      Restricted
 LocalMachine       Undefined

Undefined を指定すれば Undefined に戻すことができます。

> Set-ExecutionPolicy -Scope CurrentUser Undefined
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

すべての設定を Undefined に戻したい場合は、foreach を使うとお手軽です。

> $scope = @("Process","CurrentUser","LocalMachine");  foreach($item in $scope){Set-ExecutionPolicy -Scope $item Undefined}
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

環境変数を使用する

CurrentUserLocalMachine スコープでは、設定値はレジストリに書き込まれますが、Process スコープでは $env:PSExecutionPolicyPreference に設定が反映されます。そのため、環境変数を書き換えるだけで、Process スコープの実行ポリシーを変更できます。

初期状態では $env:PSExecutionPolicyPreference は空の状態です。

> $env:PSExecutionPolicyPreference
> # 何も表示されない。

環境変数に実行ポリシーの値を入れることで、Process スコープの実行ポリシーが変更されます。

> $env:PSExecutionPolicyPreference = "Unrestricted"
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process    Unrestricted
  CurrentUser       Undefined
 LocalMachine       Undefined

逆に空にすれば、Process スコープの実行ポリシーが Undefined に変更されます。

> $env:PSExecutionPolicyPreference = ""
PS C:\Users\WDAGUtilityAccount> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

ついでに見ておくと、Set-ExecutionPolicy コマンドレットを使った場合には、環境変数に指定した値が入っていることがわかります。

> Set-ExecutionPolicy -Scope Process Unrestricted
> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process    Unrestricted
  CurrentUser       Undefined
 LocalMachine       Undefined

> $env:PSExecutionPolicyPreference
Unrestricted

Process スコープの活用方法

Process スコープの活用方法としては、第3者にスクリプトを渡して実行してもらうときに、バッチファイル(.bat)で PowerShell スクリプトをラッピングしてあげれば、実行先環境の実行ポリシーを意識しなくて良くなります。もちろん、上記のように PowerShell を起動して、Process スコープを変更して…とやってもらってもいいですが、PowerShell に馴染みのない人にやってもらうには難易度が高いです。そんなときに、バッチファイルを作成しておけば、ただバッチファイルを実行してもらうだけで良くなるので、覚えておくと役に立つでしょう。

powershell -ExecutionPolicy Unrestricted -File .\Test-Script.ps1

もしくは環境変数の変更を意識して以下のように書いても良いでしょう。

set PSExecutionPolicyPreference=Unrestricted
powershell .\Test-Script.ps1

おわりに

PowerShell スクリプト初心者が必ずはまるであろう実行ポリシーですが、残念ながらしっかりわかりやすくまとまった情報はなかなか見つからないです。このまとめが、誰かの役に立てば幸いです。

以上