カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまに数学やデータ分析なども。

PowerShell スクリプトの実行が無効となっている場合の対処法

PowerShell ISEやPowerShell対話式コンソールからは実行できるのに、スクリプトファイル化したps1ファイルを実行しようとすると
以下のようなセキュリティエラーが発生する場合があるので、この場合の対処法についてまとめる。
今回はecho Hello PowerShellとだけ書かれたtest.ps1と言う名前のPowerShellスクリプトファイルを用意して、検証を行った。

test.ps1

echo Hello PowerShell

test.ps1を実行すると権限エラー。

PS C:\dev> .\test.ps1
.\test.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル C:\dev\test.ps1 を読み込むことができません。
詳細については、「about_Execution_Policies」(http://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\test.ps1
+ ~~~~~~~~~~
  + CategoryInfo     : セキュリティ エラー: (: ) []、PSSecurityException
  + FullyQualifiedErrorId : UnauthorizedAccess

原因

原因はデフォルトではWindowsのPowerShellスクリプト実行ポリシーによって実行が許可されていないため。
そのため、セキュリティポリシーを変更することで解消できる。
セキュリティポリシーを確認するには、PowerShellコンソールでGet-ExecutionPolicyコマンドレットを以下のように実行する。

PS C:\dev> Get-ExecutionPolicy
Restricted

このエラーが発生するたいていの場合は「Restricted」となっており、これはデフォルトでもある。
ポリシーにはいくつかの種類があり、「RemoteSigned」あたりにしておけばたいていは問題なく実行できるが、「ByPass」にしておくと全てのスクリプトが実行できるようになる。
このあたりはポリシーの意味とセキュリティレベルを考慮して設定する必要があるところだが、詳細は以下に詳しいのでリンクだけ紹介して割愛。
http://www.atmarkit.co.jp/ait/articles/0805/16/news139.html

以下、ポリシーを変更して実行するための二つの方法について述べる。

方法1: 直接実行ポリシー設定を変更する

この方法は直接ポリシーを変更するので、一度の対応で恒久的にスクリプト実行が可能になるが、管理者権限が必要なため一般ユーザ権限しかない場合はこの方法がとれない。

PS C:\dev> Set-ExecutionPolicy RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (http://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "N"): Y
Set-ExecutionPolicy : レジストリ キー 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell ' へのアクセスが拒否されました。 
既定 (LocalMachine) のスコープの実行ポリシーを変更するには、[管理者として実行] オプションを使用して Windows PowerShell を起動してください。
現在のユーザーの実行ポリシーを変更するには、"Set-ExecutionPolicy -Scope CurrentUser" を実行してください。
発生場所 行:1 文字:1
+ Set-ExecutionPolicy RemoteSigned
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo     : PermissionDenied: (:) [Set-ExecutionPolicy], UnauthorizedAccessException
  + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.SetExecutionPolicyComma nd

このように権限がない場合はエラーとなる(権限がある場合はこのコマンドで問題なく正常終了する)。
現在のユーザーに関しての権限がある場合は以下のように-Scope CurrentUserオプションを付与すると実行できる場合もある。

PS C:\dev> Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (http://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y) [A] すべて続行(A) [N] いいえ(N) [L] すべて無視(L) [S] 中断(S) [?] ヘルプ (既定値は "N"): Y

問題なく実行できた場合はこのようにポリシーが変更できたことと、正しくPowerShellスクリプトが実行できるようになる。

PS C:\dev> Get-ExecutionPolicy
RemoteSigned
PS C:\dev> .\test.ps1
Hello PowerShell

方法2: PowerShellコマンドに実行ポリシーオプションを付与してスクリプト実行する

実行ポリシーにはスコープが存在し、実は上の方法は全ユーザ、実行ユーザのスコープでポリシー変更していたが、もう一つプロセス単位のスコープも存在する。
こちらは管理者権限もなく、プロセス単位なので恒久的な設定変更も不要のため、最も手軽に試すことができる。

この方法の場合は以下のようにコマンドプロンプトでpowershellコマンドから指定すると便利。
まず、そのまま実行してみる。

c:\dev>powershell .\test.ps1
.\test.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル C :\dev\test.ps1 を読み込むことができません。
詳細については、「about_Execution_Po licies」(http://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\test.ps1
+ ~~~~~~~~~~
  + CategoryInfo     : セキュリティ エラー: (: ) []、PSSecurityException
  + FullyQualifiedErrorId : UnauthorizedAccess

最初のときと同じようにエラーとなる。
今度は実行ポリシーオプションを付与して実行する。

c:dev>powershell -ExecutionPolicy RemoteSigned .\test.ps1
Hello PowerShell

今度は正常に実行できた。さらに方法1のときのように管理者権限がなくとも実行できている。
この方法はプロセス単位なので毎回このオプションを付与する必要があるが、システム設定に影響はないためバッチプログラムをPowerShellで書く場合などに便利。

まとめ

以上PowerShellの実行ポリシーを変更してスクリプトファイルから実行するための方法を二つ見た。
管理者権限があり恒久的に許可したい場合はSet-ExecutionPolicyコマンドレットで直接変更してやるのがよい。
一方、権限がない場合やシステム設定を変更したくない場合、バッチプログラムから呼び出す場合などは、プロセススコープで実行時にスコープ指定することで手軽に変更できる。
後者の方法であれば、どんな場面でも使えるので知っておくと便利。

以上!