PowerShell実行ポリシーを管理するためのSet-ExecutionPolicy

あなたは PowerShell スクリプトをダウンロードし、それを実行して以下の悪名高いエラーメッセージに遭遇したことがありますか?そうであれば、Set-ExecutionPolicy コマンドレットとこのチュートリアルが必要です!

PowerShell Script Execution Disabled Error

この投稿では、PowerShell の実行ポリシーとそれを管理するための Set-ExecutionPolicy コマンドレットについて学びます。この投稿の終わりまでに、スクリプトの実行方法だけでなく、実行ポリシーの使用方法も理解できるようになるでしょう!

このチュートリアルは Windows PowerShell を対象に書かれており、すべてのデモンストレーションは Windows PowerShell で実行されています。実行ポリシーは Windows PowerShell に固有のものではなく、PowerShell 6+ でも非常に似たような動作をします。ただし、PowerShell 6+ を使用している場合は、動作にわずかな違いがあるかもしれません。

実行ポリシーとは何ですか?

上記で説明されたエラーに遭遇したことがあれば、実行ポリシーに遭遇したことになります。PowerShell の実行ポリシーは、悪意のあるスクリプトの実行からシステムを保護するためのセキュリティメカニズムです。実行ポリシーは、コンソールとしての PowerShell コードの実行を防ぐのではなく、スクリプトの実行を制限します。

Microsoft によれば、実行ポリシーは厳密には「セキュリティ」対策ではなく、開閉可能なゲートのようなものです。なぜなら、定義された実行ポリシーを簡単にバイパスできる方法を後で学ぶからです。

実行ポリシーは信頼に基づいています。スクリプトを信頼できる場合、それは悪意のあるものではない可能性があります。実行ポリシーは通常、すべてのスクリプトの実行を防止しません。その主な目的(特に厳密に設定された場合)は、実行しているスクリプトが証明書で暗号化されていることを信頼することです。

実行ポリシーのスコープ

実行ポリシーはスクリプトの実行を制限しますが、PowerShellは多くの異なるコンテキストでスクリプトを実行することができます。PowerShellはユーザーがログインしているコンテキストまたはグローバルマシンコンテキスト、SYSTEMとして実行されるスケジュールされたタスク、または単一のオープンされたPowerShellコンソールのスコープ内でスクリプトを実行します。

これらすべてのコンテキストに対応するために、PowerShellには5つの異なるコンテキストまたはスコープがあり、実行ポリシーを定義することができます。

  • MachinePolicy – このスコープは単一のコンピューターに限定されています。そのコンピューターにログインするすべてのユーザーに影響を与え、Active Directoryのグループポリシーオブジェクトで設定されます。定義されている場合、他のすべてのスコープより優先されます。
  • LocalMachine。これは、すべてのコンピュータユーザーに影響を与えるデフォルトのスコープであり、HKEY_LOCAL_MACHINEレジストリのサブキーに保存されます。 Set-ExecutionPolicyを使用して実行ポリシーを設定する場合、このスコープがデフォルトになります。

LocalMachineの実行ポリシーは、レジストリキーHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShellに保存されます。

  • UserPolicyUserPolicyスコープは、コンピューター上の単一のユーザーにのみ影響を与え、Active Directoryグループポリシーオブジェクトで設定されます。 Set-ExecutionPolicyではこのポリシーを変更することはできません。
  • CurrentUserCurrentUserポリシースコープは、現在のユーザーに対してのみ実行ポリシーを設定し、HKEY_CURRENT_USERレジストリハイブに保存されます。 Set-ExecutionPolicyではこのポリシーを変更することはできません。

CurrentUserの実行ポリシーは、レジストリキーHKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShellに保存されます。

  • Process – このスコープは、単一のユーザーの単一のPowerShellセッションの実行ポリシーを定義します。 Process実行ポリシースコープは、定義できる最も細かい実行ポリシーです。他の実行ポリシーとは異なり、このポリシーはレジストリではなく、PSExecutionPolicyPreferenceという環境変数に保存されます。

実行ポリシータイプ

実行ポリシーにはさまざまな「セキュリティレベル」があります。これらのレベルは、実行ポリシーの厳格さを規定します。たとえば、何もしない実行ポリシーを設定することができます。無効化されていますが、一方で、実行ポリシーはスクリプトの実行を完全に無効化することもあります。

最も緩やかなセキュリティレベルから最も制限のあるレベルまで、実行ポリシーのセキュリティレベルを設定する方法について説明しましょう。

制限なし

最も制限のないポリシーは、何も影響を与えないものです。これが「制限なし」です。制限なしの実行ポリシーは、基本的には無効化されています。実行ポリシーが制限なしの場合、ユーザーは信頼性に関係なくすべてのスクリプトを実行できます。

バイパス

制限なしタイプと同様に、バイパスに設定された実行ポリシーは何もブロックしません。

ただし、バイパス実行ポリシータイプは、厳密にはタイプではありません。定義された実行ポリシーを完全にスキップします。

未定義

あまり一般的ではありませんが、実行ポリシーを未定義に設定することで、実行ポリシーを実質的に削除することができます。実行ポリシーを未定義に設定すると、PowerShellは割り当てられたスコープからすべての実行ポリシーを完全に削除します。

非Windowsコンピュータでは、実行ポリシーは常に制限なしに設定されており、変更することはできません。

すべてのスコープが未定義に設定されている場合、PowerShellはすべてのスコープを制限されたものとして扱います。

RemoteSigned

前述の通り、実行ポリシーはスクリプトのデジタル署名によって得られた信頼に関するものです。PowerShellは、そのスクリプトの出所も考慮しています。それは、ローカルコンピュータで作成されたものなのか、インターネット上のランダムな人物によって作成されたものなのかを意味します。

ローカルコンピュータ以外で作成されたスクリプトには、基本的な信頼は置かれません。これがPowerShellが提供するRemoteSigned実行ポリシーです。RemoteSigned実行ポリシーは、すべてのスクリプトがローカルコンピュータ以外の場所で作成され、暗号化されていることを強制します。

インターネットからダウンロードされたファイルに対して、この実行ポリシーを一部回避することもできます。Unblock-Fileコマンドレットを使用してください。この動作に関する詳細情報は、後の「RemoteSignedポリシーの動作方法」セクションで説明します。

Windows Serverでは、デフォルトのポリシーとしてRemoteSignedが割り当てられています。

AllSigned

すべてのPowerShellスクリプトに暗号化署名が必要であることを確認したい場合は、実行ポリシーをAllSignedに設定してください。 RemoteSignedと同様に、この実行ポリシーはスクリプトの実行前に署名が必要です。

実行ポリシーがAllSignedに設定されている場合でも、後で説明するように、実行ポリシーを回避することはできます。

Restricted

最も制限の厳しい実行ポリシーは制限されたです。実行ポリシーが制限された場合、信頼されたかどうかに関わらず、スクリプトは一切実行されません。このポリシーはスクリプトの実行を完全に無効にします。

また、他の制限の緩いタイプとは異なり、制限されたタイプではPowerShellのフォーマットと設定ファイル(PS1XML)、モジュールスクリプトファイル(PSM1)、PowerShellプロファイルを実行できません。

デフォルトでは、すべてのWindowsクライアントは制限された実行ポリシーに設定されています。

技術的には、MicrosoftはDefaultという7番目の実行ポリシーを定義していますが、このタイプは実質的にはRemoteSigned(Windows Server)と制限された(Windowsクライアント)の別名です。

RemoteSignedポリシーの動作方法

特定のシナリオを指摘するために、RemoteSigned実行ポリシーの動作方法について説明します。この実行ポリシーは、ローカルコンピュータ以外で作成されたスクリプトの実行を防止する(学んだ通り)

しかし、PowerShellはどのようにしてスクリプトが他の場所で作成されたものであることを知るのでしょうか?データストリームです。

NTFSデータストリームの理解とクエリ

NTFSファイルシステム上でファイルを作成すると、NTFSはファイルに代替データストリーム(ADS)属性を適用します。ADSには2つのファイル属性、$Datazone.Identifierがあります。PowerShellはzone.Identifier属性を使用して、PowerShellスクリプトファイルが他の場所で作成されたかどうかを識別します。

他の属性(CompressedRead Onlyなど)とは異なり、ADS属性はファイルエクスプローラーでは非表示になっています。ただし、PowerShellを使用することで、これらのデータストリームを調査することができます。

以下のように、スクリプトへのパスとStreamパラメータを指定して、Get-Itemコマンドレットを実行します。この例では、Hello World.ps1がローカルコンピュータに作成されました。Streamプロパティに割り当てられた属性は$DATAのみです。ADS属性はありません。

Get-Item '.\Hello World.ps1' -Stream *
ADS Stream output for local file

次に、インターネットからダウンロードしたスクリプトに対して同じコマンドを実行します。すると、今度はGet-Itemが別のオブジェクトを返し、StreamZone.Identifierです。

ADS Stream output for PowerShell file downloaded from internet

ファイルにADSがあることがわかったら、Get-Contentコマンドを使用してゾーンを調べることができます。ゾーンはファイルの出所を定義します。

Get-Content .\Get-CertDetails.ps1 -Stream zone.identifier

Get-ContentZoneId値を返します。これはファイルの出所を表します。

Zone ID Value

可能なゾーンの値は以下の通りです:

Zone ID Zone
------- ---------------------
0       My Computer
1       Local Intranet Zone
2       Trusted sites Zone
3       Internet Zone
4       Restricted Sites Zone

実行ポリシーの優先順位

前述の通り、さまざまな実行ポリシーが同時に存在します。これらの実行ポリシーは組み合わさることによって、現在のセッションの設定を決定します。複数の実行ポリシーが有効な場合、優先順位が必要です。

ポリシーの優先順位は、PowerShellがさまざまなスコープで設定された異なるポリシーを適用する順序です。一部の実行ポリシーは他のものよりも優先度が高いです。

Get-ExecutionPolicy -Listを実行すると、現在有効なすべての実行ポリシーが優先度の低い順に表示されます。たとえば、MachinePolicyは優先度が低いため、LocalMachineおよびCurrentUserのポリシーが優先されます。

Get-ExecutionPolicy cmdlet output

実行ポリシーの操作

実行ポリシーの操作には、Get-ExecutionPolicyコマンドを使用して現在定義されているポリシーを確認することと、Set-ExecutionPolicyコマンドを使用して新しいポリシーを設定することの2つのコマンドがあります。

現在割り当てられているポリシーの取得

実行ポリシーを変更する前に、作業する内容を把握する必要があります。そのためには、Get-ExecutionPolicyコマンドを使用します。このコマンドは、コンピュータ上に現在割り当てられているすべてのポリシーを列挙します。

Get-ExecutionPolicyコマンドをパラメータなしで直接PowerShellコンソールで実行すると、現在のPowerShellセッションに設定されている実行ポリシーが表示されます。

Get-ExecutionPolicy cmdlet output

スコープに設定されている実行ポリシーを表示するには、Scopeパラメータを使用し、結果を表示したいスコープ名を指定します。

Get-ExecutionPolicy -Scope Process
Get-ExecutionPolicy -Scope LocalMachine
Get-ExecutionPolicy cmdlet with scope parameter output

すべてのスコープとその実行ポリシーを表示するには、以下に示すようにListパラメータを使用します。

Get-ExecutionPolicy -list
Get-ExecutionPolicy cmdlet displaying all scopes

実行ポリシーの変更

現在割り当てられている実行ポリシーを知ると、それらを変更することもできます。単一のコンピューターでポリシーを変更するには、Set-ExecutionPolicyコマンドを使用します。ただし、組織内でポリシーを一括変更する場合は、Active Directoryドメインにいる場合は常にグループポリシーを使用できます。

Set-ExecutionPolicyを使用する

まず、管理者としてPowerShellを開きます。

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

次に、Set-ExecutionPolicyコマンドを単一のパラメーター(ExecutionPolicy)と共に実行します。実行ポリシーの名前を指定します。PowerShellは実行ポリシーを変更するかどうかを確認します。変更する場合は、YまたはAを入力し、Enterキーを押します。

Change Execution Policy

上記の例でYを入力すると、PowerShellは各ステップについて続行するかどうかを確認するプロンプトを表示する場合があります。 Aを押すと、すべての後続のステップに対して続行します。

プロンプトなしでSet-ExecutionPolicyを実行する

デフォルトでは、Set-ExecutionPolicyを実行すると、実行ポリシーを変更するかどうか尋ねられます。コマンドにForceパラメータを追加することで、このプロンプトをスキップすることができます。Forceパラメータを使用すると、確認プロンプトがすべて抑制されます。

Set-ExecutionPolicy RemoteSigned -Force
Output of Set-ExecutionPolicy command when Force Parameter is used

レジストリを介してPowerShellの実行ポリシーを設定する

ほとんどの実行ポリシーはレジストリに保存されています(Processを除く)。したがって、レジストリを直接変更することで実行ポリシーを変更することもできます。

レジストリを介して実行ポリシーを変更するには:

  1. Windowsレジストリエディター(regedit)または選択したレジストリ編集ツールを開きます。

2. 変更したい実行ポリシーのスコープのレジストリキーに移動します。

LocalMachineHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

CurrentUserHKEY_CURRENT_USER\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

3. レジストリキーを右クリックし、ExecutionPolicyという新しい文字列値を作成します。

4. 新しく作成したExecutionPolicy文字列値をダブルクリックし、実行ポリシーの名前(RestrictedRemoteSignedAllSignedUnrestricted、またはUndefined)を入力します。

5. 同じキーに別の文字列値を作成し、Pathと呼びます。 Pathの文字列値はPowerShellエンジンへのパスを表します。 Pathの値は、Windows PowerShellエンジンを指すC:\Windows\System32\WindowsPowerShell\v1.0\powershell.exeになるようにしてください。

Registry path for ExecutionPolicy in registry for current user

CurrentUserの実行ポリシーは、LocalMachineのポリシーを上書きします。レジストリにCurrentUserポリシーが設定されており、Set-ExecutionPolicyを使用して実行ポリシーを変更しようとすると、デフォルトではポリシーはLocalMachineのスコープに設定されますが、PowerShellは以下のエラーを返します。

Execution Policy Permission Denied

グループポリシーを使用してPowerShell実行ポリシーを設定する

Active Directoryを使用する組織の場合、すべてのWindowsマシンに回り、Set-ExecutionPolicyコマンドレットを実行する必要はありません。代わりに、グループポリシーで一括管理することができます。

グループポリシーを使用して実行ポリシーを管理するには:

グループポリシーオブジェクトを作成する

  1. ドメインコントローラーまたはドメインに参加しているワークステーションで、グループポリシーマネージメントアプリケーションを開きます。
Group Policy Management Console

2. ドメイン —> Active Directoryのフォレスト —> グループポリシーオブジェクトを展開します。

Select Group Policy Objects node

3. グループポリシーオブジェクトを右クリックし、新規をクリックします。

4. GPOに名前を付けてください。このチュートリアルでは、GPOの名前は「PowerShell実行ポリシー」とします。

Create new Group Policy Object

5. 新しく作成したGPOを右クリックし、「編集」をクリックしてください。

6. 「コンピュータの構成」→「ポリシー」→「管理用テンプレート」→「Windowsコンポーネント」→「Windows PowerShell」に移動してください。

Navigate to the setting in Group Policy Object

7. 右ウィンドウペインの設定を開き、「スクリプトの実行を許可する」設定を開いてください。

Turn on Script Execution Policy

8. 「スクリプトの実行を許可する」ボックスで、「有効」オプションを選択してください。以下に表示されるオプションのいずれかを選択できます:

9. 今、望むポリシーに実行ポリシーを変更してください。

  • 署名されたスクリプトのみ許可 – 信頼できるパブリッシャーが署名したスクリプトのみを実行できます。
  • ローカルスクリプトとリモート署名スクリプトを許可 – ローカルスクリプトは実行できますが、インターネットからダウンロードしたスクリプトは信頼できるパブリッシャーによって署名されている必要があります。
  • すべてのスクリプトを許可 – すべてのスクリプトを実行できます。
List Execution Policy

グループポリシーオブジェクトを割り当てる

GPOが作成されたら、それを対象のコンピュータに割り当てる時が来ました。そのためには、GPOをActive Directoryの組織単位(OU)に割り当てる必要があります。

新しいGPOを作成する代わりに既存のGPOを編集した場合、そのGPOは既にOUに割り当てられている可能性があります。

  1. グループポリシー管理で、ドメイン —> <ご使用のActive Directoryフォレスト> —> <お好きなOU>に移動します。

2. OUを右クリックし、既存のGPOをリンクする…を選択します。

Link an Existing GPO…

3. 作成したGPO(PowerShell実行ポリシー)を選択し、OKをクリックします。

Select the GPO

以下のように、OUに割り当てられたGPOが表示されます。

Link the Group Policy Object

この時点で、定義されたグループポリシーの更新間隔を待つか、対象のコンピュータでgpupdateコマンドを実行して更新を強制することができます。

ローカルポリシーの変更をロックする

実行ポリシーを変更するGPOが有効になると、ローカルユーザーはローカルのPowerShellコンソールを介してポリシーを変更できなくなります。試みると、以下のようなエラーが表示されます。

Error on trying to changing execution policy manually

実行ポリシーを完全にバイパスする

先述のように、実行ポリシーは必ずしもセキュリティ対策として意図されたものではありません。なぜなら、いくつかの方法で完全にバイパスすることができるからです。

-ExecutionPolicy Bypassパラメータを使用する

他の実行ポリシーとは異なり、Bypassポリシーは通常、PowerShellコンソールではなくpowershell.exeエンジン実行時に管理者として設定されます。

たとえば、実行ポリシーを完全にスキップしてHello World.ps1というスクリプトを実行するには、powershell.exeを呼び出し、Bypassパラメータを使用し、ファイルパスを以下のように指定します。

powershell.exe -executionpolicy bypass -file '.\Hello World.ps1'
ByPass Execution Policy using bypass execution policy

スクリプトの読み込みと生コードの実行

また、スクリプトの内容を最初に読み込んでそれを直接PowerShellエンジンに渡すことで、実行ポリシーを回避することもできます。これにより、各コマンドが個別に実行され、一度にスクリプト全体としてではなく実行されます。

以下のように、実行ポリシーがRestrictedに設定されていますが、スクリプトを読み込んでpowershell.exeに渡すことで、それでも動作します。

このアプローチは、PowerShell ISEやVisual Studio CodeなどのPowerShellエディタでスクリプトを開き、行を選択してF8キーを押すのと似ています。

Get-Content '.\Hello World.ps1' | powershell.exe -noprofile
Alternative way to Bypass Execution Policy

結論

これでPowerShellの実行ポリシーに関するすべてを知ることができるはずです。これらは厳密にはセキュリティ対策ではありませんが、組織のポリシーに従って組織内で管理する必要があります。

Source:
https://adamtheautomator.com/set-executionpolicy/