※ 本記事はレジストリを触ります。本記事の内容を実行する際は自己責任でお願いいたします。 ※ 本記事の内容をご自身の責任で実行して、万が一障害が発生しても責任は取れません。
はじめに
今回は、PowerShellスクリプト(.ps1)をの権限設定の注意について説明します。 せっかく作ったPowerShellスクリプト(.ps1)を本番などにデプロイする際、検証環境で動いたPowerShellスクリプトが、いざテスト環境や本番環境にコピーすると実行できない。 そんな経験はありませんか?
これは、PowerShellの初期スクリプト実行セキュリティ・ポリシー設定では、PowerShellスクリプト(.ps1)の実行が許可されていないことを忘れているために起こります。 Powerhshellのスクリプト実行セキュリティ・ポリシーの設定は、検証環境など自分の環境で一度実行すると「その後触らなくなる事が多い」ため忘れがちです。 本記事で紹介するので、ご参考にどうぞ。 説明の最下部に、任意でPowerShellスクリプト実行セキュリティ・ポリシーを変更するバッチを公開しておきます。
TechNetによる解説
Poershellのスクリプト実行に関しては、MSのTechNetに詳細記述があります。 英語に自信のある方は、ここを見ればこの記事いりませんww
Windows Powershell Owner's Manual -- Running Windows PowerShell Scripts (英語記事)
ポイント
PowerShellスクリプトの初回実行に関するポイントは以下の5点です。
@IT -- PowerShellスクリプトの実行セキュリティ・ポリシーを変更する
- 実行セキュリティ・ポリシーには【署名有無】と【ローカル・スクリプトと非ローカル・スクリプト】で4種類ある
- Powerhshellのスクリプト実行セキュリティ・ポリシーはデフォルト無効
- 管理者権限で起動したPowerShellを使ってps1実行
- 一度変更したセキュリティ・ポリシーは維持される
- x64環境とx86環境では、実行セキュリティ・ポリシーを別々に持っている
私自身が陥った例
検証環境でPowerShellスクリプトが上手く動いたー! よーし、次はプレ本番環境でリリース前検証だー。 ………あれ……?検証環境では動いたのにPowerShellスクリプト(.ps1)が実行できない!? ユーザー権限でPowerShellを実行したからかな?「管理者として実行」すれば……
えっ、起動できない……?!「スクリプトの実行が許可されていない」って、……検証環境では動くのに? .....気を取り直して、原因を見ていきましょう。
PowerShellのスクリプト実行セキュリティ・ポリシーとは
PowerShellには、スクリプト実行セキュリティ・ポリシーが4種類あります。 ※セキュリティポリシーは4種以外に、BypassやUndefinedの2つも有りますが、通常は利用しないと見込んで省きます。 この内、よくスクリプト実行のために設定されるのがRemoteSignedです。
| 実行ポリシー | 意味 |
|---|---|
| Restricted | すべてのスクリプトが実行禁止。PowerShellインストール直後のデフォルト設定 |
| AllSigned | 署名されているスクリプトのみが実行可能。署名されていないスクリプトは実行禁止 |
| RemoteSigned | ローカルに保存されているスクリプトは実行可能。インターネットからダウンロードしたスクリプト(非ローカルのスクリプト)は、署名されているもののみが実行可能 |
| Unrestricted | すべてのスクリプトが実行可能。ただしインターネットからダウンロードしたスクリプトは、実行するかどうかが確認されるので、ユーザーが明示的に許可した場合のみ実行される |
Windows x64環境を利用している場合の注意
Window x64bit環境ではPowerShellはx64版とx86版の2つがインストールされます。 試しに、powershellで検索して見てください。 Windows x64環境では、2種類が表示されたはずです。(Windows PowerShell ISEは省いています)
- Windows PowerShell
- Windows PowerShell (x86)
後段で説明しますが、PowerShellのスクリプト実行セキュリティ・ポリシーは、レジストリ値に保存されます。 当然、x64版PowerShellとx86版PowerShellではレジストリ値は保存パスが異なります。 そのため、PowerShellを呼び出すアプリケーションが、どちらのPowerShellを呼ぶかによって、スクリプト実行セキュリティ・ポリシーを変更するべきPowerShell環境も異なります。 ※Windows x64環境におけるx64とx86それぞれのPowerShell.exe実行パスは次の通りです。
:x64 PowerShell C:\Windows\System32\PowerShell\1.0\powershell.exe :x86 PowerShell C:\Windows\SysWOW64\PowerShell\1.0\powershell.exe
※Windows x86環境におけるPowerShell.exe実行パスは次の通りです。
:x86 PowerShell
C:\Windows\System32\PowerShell\1.0\powershell.exe
デフォルトのスクリプト実行セキュリティ・ポリシーは?
PowerShellで、一度もスクリプトを実行したことがない環境では、スクリプト実行セキュリティ・ポリシーはRestrictedです。
- Restricted: すべてのスクリプトが実行禁止。PowerShellインストール直後のデフォルト設定
先に上げた初めてWindows PowerShellを実行する環境において、現在のセキュリティポリシーを確認します。
Step1. まずはPowerShellを起動します。(x64環境では、Windows PowerShell (x64)を起動するかWindows PowerShellを起動するかを選びます) Step2. 現在のセキュリティポリシー確認には、以下のコマンドレットを利用します。
Get-ExecutionPolicy
Step3. 結果、初めて起動したPowerShellではRestrictedと表示されました。 これでは、.ps1スクリプトを読み込むことが出来ません。 そこでPowerShellの実行セキュリティ・ポリシーを変更していきます。
スクリプト実行セキュリティ・ポリシーを変更する
セキュリティポリシーを変更するには、専用コマンドレットによるレジストリ設定の変更を要します。 ※レジストリアクセスが発生するため、UACが有効になったWindows Vista/7/8/2008R2/2012では『管理者として実行』されたPowerShellでしか以下のコマンドレットを実行できません。 ※Windows XP SP3や2003 R2などのUACが存在しないOSでは、管理者ユーザーPowerShellを起動すれば以下のコマンドレットを実行可能です。
セキュリティポリシー変更には、以下のコマンドレットを利用します。
Set-ExecutionPolicy [セキュリティポリシー]
例えば、RestrictedをRemoteSignedに変更する場合は、以下のように実行します。
Set-ExecutionPolicy RemoteSigned
※確認ダイアログが出るので、y/nを選択します。 変更後の、 現在のセキュリティポリシー確認には再度以下のコマンドレットを利用します。
Get-ExecutionPolicy
※ ちなみに、『管理者として実行』されていないPowerShellでセキュリティポリシーを変更しようとすると、レジストリにアクセスできないことを示すエラーが表示されます。
実行セキュリティ・ポリシー設定は維持される
前述の通り、セキュリティポリシーは、レジストリ値に書き込まれています。 そのため、一度セキュリティポリシーを変更すれば、以降は明示的にセキュリティポリシーを変更しない限り維持されます。
つまり、前節のように一度RemoteSignedに変更した後は、ユーザー権限でPowerShellを起動しても(バッチ連動...etc)、.ps1スクリプトを実行することが出来ます。 参考までに保存されるレジストリパスは次の通りです。
※Windows x64環境でのレジストリ保存パス
# x64 PowerShell HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.Powershell # x86 PowerShell HKLM\SOFTWARE\Wow6432node\Microsoft\PowerShell\1\ShellIds\Microsoft.Powershell
※Windows x86環境でのレジストリ保存パス
# x86 PowerShell HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.Powershell
自動的にWindows x64とx86のバージョンに応じてスクリプト実行セキュリティ・ポリシーを変更するバッチ
めんどくさい方の為に、以下のバッチファイルを作成しました。
利用方法
- メモ帳などにコピーした後、拡張子を.batにして保存してください
- 保存したバッチファイルを管理者として実行してください
- 本当に変更するか、ダイアログが表示されるので、任意の選択をしてください
@ECHO OFF REM ============================================================== ECHO Now Checking Windows x64/x86 version information...... ECHO . ECHO .. ECHO ... ECHO .... ECHO ..... ECHO. IF EXIST %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe GOTO x64 GOTO x86 REM ============================================================== :x64 REM ============================================================== ECHO ** Your System was detected as x64bit Windows ** ECHO. ECHO ---------------------------------------- Echo x86版 PowerShell の LocalMachine 実行ポリシー変更 ECHO ---------------------------------------- ECHO ** Currenct ExecutionPolisy ** %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe -Command "Get-ExecutionPolicy -list" ECHO. ECHO ** Changing ExecutionPolisy ** %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Confirm" ECHO. ECHO ** Changed After ExecutionPolisy ** %SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe -Command "Get-ExecutionPolicy -list" ECHO ---------------------------------------- Echo x64版 PowerShell の LocalMachine 実行ポリシー変更 ECHO ---------------------------------------- ECHO ** Currenct ExecutionPolisy ** %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Get-ExecutionPolicy -list" ECHO. ECHO ** Changing ExecutionPolisy ** %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Confirm" ECHO. ECHO ** Changed After ExecutionPolisy ** %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Get-ExecutionPolicy -list" GOTO EOF REM ============================================================== :x86 REM ============================================================== ECHO ** Your System was detected as x86bit Windows ** ECHO. ECHO ---------------------------------------- Echo x86版 PowerShell の LocalMachine 実行ポリシー変更 ECHO ---------------------------------------- ECHO ** Currenct ExecutionPolisy ** %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Get-ExecutionPolicy -list" ECHO. ECHO ** Changing ExecutionPolisy ** %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy RemoteSigned -Scope LocalMachine -Confirm" ECHO. ECHO ** Changed After ExecutionPolisy ** %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Get-ExecutionPolicy -list" GOTO EOF REM ============================================================== :EOF PAUSE