PowerShellのスクリプトは、デフォルトでは「このシステムではスクリプトの実行が無効になっているため……」というエラーが表示され、実行されないようになっている。スクリプトを利用するのに必要な「実行ポリシー」の変更手順やその種類について説明する。
対象:PowerShell 2.x/3.x/4.x/5.x
PowerShellのスクリプトは「.ps1」という拡張子のファイルに保存することになっている。だが、セキュリティのためデフォルトでは、「.ps1」のスクリプトファイルの実行が禁止されている。エクスプローラ上で.ps1ファイルをダブルクリックしても、単にテキストエディタで開かれるだけだ。これは、ユーザーや管理者が知らないうちにPowerShellを悪用したウイルスなどがインストールされ、実行されないようにするためだ。
.ps1ファイルを実行するかどうかは、PowerShellの「実行ポリシー(Execution Policy)」で制御されている。ポリシーには次の5種類がある。Windows Server 2012 R2以外のWindows OSでは、デフォルトで「Restricted」のポリシーが設定されているので、スクリプトとして実行されることはない(関連記事「PowerShellスクリプティングの第一歩」も参照)。
実行ポリシー | 署名付き | 署名なし/ローカル | 署名なし/非ローカル | 概要 |
---|---|---|---|---|
Restricted | × | × | × | 全てのスクリプトが実行禁止。PowerShellまたはWindows OSインストール直後のデフォルト設定(Windows Server 2012 R2を除く) |
AllSigned | ○ | × | × | 署名されているスクリプトのみが実行可能。署名されていないスクリプトは実行禁止 |
RemoteSigned | ○ | ○ | × | ローカルに保存されているスクリプトは実行可能。インターネットからダウンロードしたスクリプト(非ローカルのスクリプト)は、署名されているもののみが実行可能。Windows Server 2012 R2では、この設定がデフォルト |
Unrestricted | ○ | ○ | △ | 全てのスクリプトが実行可能。ただしインターネットからダウンロードしたスクリプトは、実行するかどうかが確認されるので、ユーザーが明示的に許可した場合のみ実行される |
Bypass | ○ | ○ | ○ | 警告やユーザーへの確認なしに、全てのスクリプトが実行可能 |
PowerShellスクリプトの実行ポリシー スクリプトには署名付きと署名なし、ローカルスクリプトと非ローカルスクリプトという違いがあり、ポリシーによってそれぞれ実行できるかどうかが決まる。デフォルトでは全てのスクリプトが実行不可能になっており、他のポリシーに変更するまで、実行できない。 ○:実行可能、△:実行時にユーザーの確認が必要、×:実行不可 |
この表から分かるように、スクリプトには署名付きと署名なし、ローカルスクリプトと非ローカルスクリプトという種類がある。
スクリプトには、その正当性を証明/アピールするために、電子署名を付けることができる。この署名には、公的な証明書機関が発行した証明書に基づくデジタル証明書や、(テスト用の)自己発行の証明書が利用できる。証明書が付けられたスクリプトだけに実行を限定することにより、不正なスクリプトによってシステムが破壊されるなどのセキュリティ上のリスクを抑えることができる(必ずしも「署名が付いている=悪意のないスクリプト」が当てはまらないことに注意してほしい)。
スクリプトファイルが保存されている場所(もしくはスクリプトファイルを入手した経路)によって、ローカルスクリプトと非ローカルスクリプト(インターネット経由で入手したスクリプト)という2種類に分類できる。
ローカルのスクリプトとは、ローカルの(物理的な)ディスク上に保存されているスクリプトを指す。例えばC:ドライブ(すなわちローカルなディスク)に保存されている「C:\MyScript\testps.ps1」というファイルはローカルのスクリプトと見なされる。
ただしネットワークドライブをローカルにマップしている場合、そのドライブもローカルと見なされる。また「\\server1\user1\MyScript\testps.ps1」のように、単一ラベルのコンピュータ名(ドメイン名を持たない、単一のコンピュータ名)から始まるUNCパスのファイルも、ローカルとして扱われる。
これに対し、インターネットからダウンロードした.ps1ファイルや、FQDN/IPアドレスから始まるUNC名を持つファイルは、非ローカルのファイルとして扱われる。例えば「http://www.example.com/MyScript/testps.ps1(から取得したファイル。次の「ZoneIDについて」参照)」や「\\server1.example.com\user1\MyScript\testps.ps1」のようなファイルは、非ローカルと見なされる。
FQDNやIPアドレス、サーバ名の表記の違いによるローカルと非ローカルの判断は、Internet Explorer(IE)における「インターネットゾーン」と「イントラネットゾーン」の違いと同じである。ゾーンの種類や確認方法については、関連記事「IEのセキュリティ設定を変更してセキュリティ機能を強化する」「IE9でゾーン情報を確認する」を参照していただきたい。
インターネットからダウンロードしたスクリプトファイルをローカルのディスク上に保存しても、それは非ローカルのスクリプトと見なされる。これは「ZoneID」という入手元のゾーンを表す情報がスクリプトファイルに付けられているからだ。ZoneIdの詳細は、関連記事「XP SP2のZoneIdとは?」を参照していただきたい。
このZoneIdが付いているファイルは、ローカルのディスク上にあってもインターネット経由で取得したものとされ、非ローカルスクリプトとしてのセキュリティの制限を受ける。ただし、FATファイルシステムへコピーしたり、ZoneIDを無視するアプリケーションを使ったり、代替ストリーム情報を明示的に削除したりするとZoneID情報がファイルから欠落してしまうので、注意が必要である(Tech TIPS「streamsコマンドでNTFSの代替データストリーム情報を表示/削除する」「dirやPowerShellでNTFSの代替データストリーム情報を表示する」参照)。
PowerShellでは、スクリプトの署名や種類に応じて、先に挙げた5種類の実行ポリシーを選択できるようになっている。とはいえ、「AllSigned」にすると常に署名が要求されるようになるので、使い勝手はよくないだろう。テスト用のスクリプトや、Webページ上で解説されているようなスクリプトを利用するだけでも、いちいち署名しないと実行できないからだ。
「Unrestricted」や「Bypass」だとほとんど制限なく実行できるため、セキュリティ上はあまり好ましくない。そのため、「RemoteSigned」(ローカルスクリプトはそのまま実行、非ローカルは署名を要求)を使うのが現実的と思われる。
現在の実行ポリシーを確認するには、Get-ExecutionPolicyコマンドレットを利用する。「Get-ExecutionPolicy」を実行すると、現在の実行ポリシーが返ってくる(デフォルトでは「Restricted」)。
実行ポリシーを設定するには、管理者権限で起動したPowerShellでSet-ExecutionPolicyコマンドレットを実行する。例えば、ローカルに保存されているスクリプトのみを実行可能にする実行ポリシーを設定するには、「Set-ExecutionPolicy RemoteSigned」を実行する(PowerShell 5.x以前では、「実行ポリシーを変更しますか?」の既定値は"Y"なので注意)。
なお、PowerShellを管理者権限で起動するには、以下のいずれかの手順を実行する。
Windows 10では、クイックアクセスメニュー([スタート]ボタンを右クリックするか、[Windows]+[X]キーを押すと表示される)から、[Windows PowerShell 管理者]を選択してもよい。
実行ポリシーをデフォルト設定に戻すには、「Set-ExecutionPolicy Restricted」を実行すればよい。
ポリシーによってPowerShellスクリプトの実行が禁止されている場合、次のようなメッセージが表示される。
なおセキュリティのため、スクリプトを実行するには、フルパス名か「.\」で始まる相対パス名を指定する必要がある。例えば「testsp.ps1」と指定するのではなく、「.\testsp.ps1」や「c:\myscript\testsp.ps1」のようにする。詳細については「Windows PowerShellコマンド&スクリプティング入門」を参照していただきたい。
次はデジタル署名が要求されているのに、署名されていないスクリプトを実行しようとした場合の例である。署名がないと、このようにエラーとなり、実行されない。
実行ポリシーでUnrestrictedを選択した場合は、インターネット(インターネットゾーン)から入手したファイルかどうかが判断され、そうならば、実行するかどうかを確認する問い合わせが表示される。単に[Enter]キーを押すか、[D]キーを押すと実行が中断され、[R]キーを押した場合にのみ実行される。
この例では[Enter]キーを押してみた。すると上記のようなメッセージが表示され、実行が中断された。
上記のように確認が求められる非ローカルスクリプトは、Unblock-Fileコマンドレットを実行すると、以後はローカルスクリプトとして扱われるようになる。
Unblock-File <スクリプトファイル名>
なお手元のPCで試したところ、ドライブにマップしたネットワークドライブや単一ラベルのサーバ名を使ったUNCパス上にあるインターネットゾーンのスクリプトファイルでは、このような問い合わせなしに、すぐに実行されることがあった(物理的なローカルディスク上のインターネットゾーンファイルや、FQDNによるUNCパスの場合は上の例のように動作する)。ゾーンの自動判定の機能をあまり信用しない方がよいだろう。
■更新履歴
【2017/12/08】PowerShell 5.xの情報を反映して、画面などを更新しました。
【2015/03/23】PowerShell 2.0〜4.0の情報を反映しました。
【2008/05/16】初版公開。
Copyright© Digital Advantage Corp. All Rights Reserved.