tech.guitarrapc.cóm

Technical updates

PowerShellスクリプト(.ps1)を初回実行する際のスクリプト実行セキュリティ・ポリシーについて

※ 本記事はレジストリを触ります。本記事の内容を実行する際は自己責任でお願いいたします。 ※ 本記事の内容をご自身の責任で実行して、万が一障害が発生しても責任は取れません。

はじめに

今回は、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のバージョンに応じてスクリプト実行セキュリティ・ポリシーを変更するバッチ

めんどくさい方の為に、以下のバッチファイルを作成しました。

利用方法

  1. メモ帳などにコピーした後、拡張子を.batにして保存してください
  2. 保存したバッチファイルを管理者として実行してください
  3. 本当に変更するか、ダイアログが表示されるので、任意の選択をしてください
@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