簡単な説明
PowerShell のスコープの概念について説明し、要素のスコープを設定および変更する方法を示します。
長い説明
PowerShell では、変数、エイリアス、関数、および PowerShell ドライブ (PSDrives) へのアクセスを、読み取りと変更が可能な場所を制限することによって保護します。 PowerShell では、スコープルールを使用して、変更しない項目を誤って変更しないようにします。
スコープの基本的な規則を次に示します。
スコープは入れ子にすることができます。 外側のスコープは親スコープと呼ばれます。 入れ子になったスコープは、その親の子スコープです。
項目は、明示的にプライベートにしない限り、作成されたスコープと任意の子スコープに表示されます。 変数、エイリアス、関数、または PowerShell ドライブは、1つまたは複数のスコープに配置できます。
スコープ内で作成した項目は、別のスコープを明示的に指定しない限り、その項目が作成されたスコープ内でのみ変更できます。
スコープ内に項目を作成し、その項目の名前を別のスコープ内の項目と共有すると、元の項目は新しい項目の下で非表示になりますが、オーバーライドまたは変更されることはありません。
PowerShell のスコープ
PowerShell では、次のスコープがサポートされます。
グローバル: PowerShell の起動時に有効なスコープ。 PowerShell の起動時に存在する変数と関数は、自動変数やユーザー設定変数など、グローバルスコープで作成されています。 PowerShell プロファイル内の変数、エイリアス、および関数も、グローバルスコープで作成されます。
Local: 現在のスコープ。 ローカルスコープには、グローバルスコープまたはその他のスコープを指定できます。
スクリプト: スクリプトファイルの実行中に作成されるスコープです。 スクリプト内のコマンドだけがスクリプトスコープで実行されます。 スクリプト内のコマンドに対して、スクリプトスコープはローカルスコープです。
注意
プライベートはスコープではありません。 これは、項目が定義されているスコープ外の項目の表示を変更するオプションです。
親と子のスコープ
新しいスコープを作成するには、スクリプトまたは関数を実行するか、セッションを作成するか、PowerShell の新しいインスタンスを開始します。 新しいスコープを作成すると、結果は親スコープ (元のスコープ) と子スコープ (作成したスコープ) になります。
PowerShell では、すべてのスコープがグローバルスコープの子スコープですが、多くのスコープと多数の再帰的なスコープを作成できます。
項目をプライベートに明示的に設定しない限り、親スコープ内の項目は子スコープで使用できます。 ただし、子スコープで作成および変更した項目は、項目の作成時にスコープを明示的に指定しない限り、親スコープには影響しません。
継承
子スコープは、親スコープから変数、エイリアス、および関数を継承しません。 アイテムがプライベートでない限り、子スコープは親スコープ内のアイテムを表示できます。 また、親スコープを明示的に指定することによって項目を変更できますが、項目は子スコープの一部ではありません。
ただし、項目のセットを使用して子スコープが作成されます。 通常は、 Allscopeオプションを持つすべてのエイリアスが含まれます。 このオプションについては、この記事の後半で説明します。 これには、 Allscopeオプションを持つすべての変数に加えて、一部の自動変数が含まれます。
特定のスコープ内の項目を検索するには、またはの Scope パラメーターを使用し Get-Variable
Get-Alias
ます。
たとえば、ローカルスコープ内のすべての変数を取得するには、次のように入力します。
Get-Variable -Scope local
グローバルスコープ内のすべての変数を取得するには、次のように入力します。
Get-Variable -Scope global
スコープ修飾子
変数、別名、または関数の名前には、次のいずれかのオプションのスコープ修飾子を含めることができます。
global:
-名前がグローバルスコープ内に存在することを指定します。local:
-名前がローカルスコープ内に存在することを指定します。 現在のスコープは、常にローカルスコープです。private:
-名前がプライベートであり、現在のスコープからのみ参照可能であることを指定します。script:
-名前がスクリプトスコープに存在することを指定します。 スクリプトスコープは、最も近い祖先スクリプトファイルのスコープ、または最も近い祖先スクリプトファイルがない場合はグローバルです。using:
-やなどのコマンドレットを使用してスクリプトを実行中に、別のスコープで定義された変数にアクセスするために使用されStart-Job
Invoke-Command
ます。workflow:
-名前がワークフロー内に存在することを指定します。 注: ワークフローは、PowerShell Core ではサポートされていません。<variable-namespace>
-PowerShell PSDrive プロバイダーによって作成された修飾子。 次に例を示します。名前空間 説明 Alias:
現在のスコープで定義されている別名 Env:
現在のスコープで定義されている環境変数 Function:
現在のスコープで定義されている関数 Variable:
現在のスコープで定義されている変数
スクリプトの既定のスコープは、スクリプトのスコープです。 関数および別名の既定のスコープは、スクリプトで定義されている場合でも、ローカルスコープです。
スコープ修飾子の使用
新しい変数、別名、または関数のスコープを指定するには、スコープ修飾子を使用します。
変数のスコープ修飾子の構文は次のとおりです。
$[<scope-modifier>:]<name> = <value>
関数のスコープ修飾子の構文は次のとおりです。
function [<scope-modifier>:]<name> {<function-body>}
スコープ修飾子を使用しない次のコマンドは、現在のスコープまたはローカルスコープに変数を作成します。
$a = "one"
グローバルスコープで同じ変数を作成するには、スコープ修飾子を使用し global:
ます。
$global:a = "one"
スクリプトスコープで同じ変数を作成するには、スコープ修飾子を使用し script:
ます。
$script:a = "one"
関数でスコープ修飾子を使用することもできます。 次の関数定義は、グローバルスコープに関数を作成します。
function global:Hello {
Write-Host "Hello, World"
}
スコープ修飾子を使用して、異なるスコープ内の変数を参照することもできます。
次のコマンドは、変数を参照します。この変数は、 $test
まずローカルスコープで、次にグローバルスコープにあります。
$test
$global:test
Using:
スコープ修飾子
を使用すると、リモートコマンドでローカル変数を識別する特別なスコープ修飾子を使用できます。 修飾子を指定しない場合、PowerShell ではリモートコマンド内の変数をリモートセッションで定義する必要があります。
Using スコープ修飾子は、PowerShell 3.0 で導入されました。
詳細については、「 about_Remote_Variables」を参照してください。
AllScope オプション
変数とエイリアスには、 Allscopeの値を取ることができるオプションプロパティがあります。 Allscopeプロパティを持つアイテムは、作成した子スコープの一部になりますが、親スコープによってさかのぼって継承されることはありません。
Allscopeプロパティを持つアイテムは、子スコープに表示され、そのスコープの一部になります。 任意のスコープ内の項目に対する変更は、その変数が定義されているすべてのスコープに影響します。
スコープの管理
いくつかのコマンドレットには、特定のスコープ内の項目を取得または設定 (作成および変更) できるスコープパラメーターがあります。 次のコマンドを使用して、スコープパラメーターを持つセッション内のすべてのコマンドレットを検索します。
Get-Help * -Parameter scope
特定のスコープで参照できる変数を検索するには、のパラメーターを使用し Scope
Get-Variable
ます。 表示される変数には、グローバル変数、親スコープ内の変数、および現在のスコープ内の変数が含まれます。
たとえば、次のコマンドは、ローカルスコープで参照できる変数を取得します。
Get-Variable -Scope local
特定のスコープで変数を作成するには、スコープ修飾子またはのスコープパラメーターを使用し Set-Variable
ます。 グローバルスコープに変数を作成するコマンドを次に示します。
New-Variable -Scope global -Name a -Value "One"
New-Alias
また、、 Set-Alias
、またはコマンドレットの scope パラメーターを使用して、スコープを指定することもでき Get-Alias
ます。 グローバルスコープにエイリアスを作成するコマンドを次に示します。
New-Alias -Scope global -Name np -Value Notepad.exe
特定のスコープ内の関数を取得するに Get-Item
は、スコープ内でコマンドレットを使用します。 Get-Item
コマンドレットにスコープパラメーターがありません。
注意
Scopeパラメーターを使用するコマンドレットについては、数値でスコープを参照することもできます。 この数値は、あるスコープと別のスコープの相対的な位置を表します。 スコープ0は、現在のスコープまたはローカルスコープを表します。 スコープ1は、直接の親スコープを示します。 スコープ2は、親スコープの親を示します。 多数の再帰的なスコープを作成した場合は、番号付きスコープが役立ちます。
スコープでのドットソース表記の使用
スクリプトと関数は、スコープのすべての規則に従います。 これらは特定のスコープで作成し、コマンドレットパラメーターまたはスコープ修飾子を使用してスコープを変更しない限り、そのスコープにのみ影響します。
ただし、ドットソース表記を使用して、スクリプトまたは関数を現在のスコープに追加することができます。 次に、スクリプトが現在のスコープで実行されると、スクリプトによって作成される関数、エイリアス、および変数が現在のスコープで使用できるようになります。
関数を現在のスコープに追加するには、関数呼び出しで、関数のパスと名前の前にドット (.) とスペースを入力します。
たとえば、スクリプトのスコープ (スクリプトの既定値) の C:\Scripts ディレクトリから Sample.ps1 スクリプトを実行するには、次のコマンドを使用します。
c:\scripts\sample.ps1
ローカルスコープで Sample.ps1 スクリプトを実行するには、次のコマンドを使用します。
. c:\scripts.sample.ps1
呼び出し演算子 (&) を使用して関数またはスクリプトを実行すると、現在のスコープには追加されません。 次の例では、呼び出し演算子を使用します。
& c:\scripts.sample.ps1
呼び出し演算子の詳細については、 about_operatorsを参照してください。
Sample.ps1 スクリプトによって作成されるエイリアス、関数、または変数は、現在のスコープでは使用できません。
スコープを使用しない制限
いくつかの PowerShell の概念は、スコープに似ています。また、スコープと対話します。 これらの概念は、スコープまたはスコープの動作と混同される可能性があります。
セッション、モジュール、および入れ子になったプロンプトは自己完結型の環境ですが、セッション内のグローバルスコープの子スコープではありません。
セッション
セッションとは、PowerShell が実行される環境です。 リモートコンピューターにセッションを作成すると、PowerShell によって、リモートコンピューターへの永続的な接続が確立されます。 永続的な接続では、複数の関連するコマンドにセッションを使用できます。
セッションは包含環境であるため、独自のスコープを持ちますが、セッションは作成されたセッションの子スコープではありません。 セッションは、独自のグローバルスコープで開始されます。 このスコープは、セッションのグローバルスコープに依存しません。 セッションでは、子スコープを作成できます。 たとえば、スクリプトを実行して、セッションに子スコープを作成できます。
モジュール
Powershell モジュールを使用して、PowerShell ツールを共有し、配布することができます。 モジュールは、コマンドレット、スクリプト、関数、変数、別名、およびその他の便利な項目を格納できる単位です。 明示的に定義されていない限り、モジュール内の項目にはモジュールの外部からアクセスできません。 そのため、セッションにモジュールを追加し、他の項目がセッションのコマンドレット、スクリプト、関数、およびその他の項目をオーバーライドする可能性があることを心配することなく、パブリック項目を使用できます。
モジュールのプライバシーはスコープと同様に動作しますが、セッションにモジュールを追加してもスコープは変更されません。 また、モジュールは独自のスコープを持っていませんが、すべての PowerShell スクリプトと同様に、モジュール内のスクリプトには独自のスコープがあります。
既定では、モジュールは現在の_スコープ_ではなく、現在の_セッション状態_の最上位レベルに読み込まれます。 これは、モジュールのセッション状態またはグローバルセッション状態である可能性があります。 グローバルスコープにいる場合は、モジュールがグローバルセッション状態に読み込まれます。 すべてのエクスポートは、グローバルテーブルに配置されます。
Module1_内_から module2 を読み込むと、グローバルセッション状態ではなく、module2 が module1's session 状態に読み込まれます。 Module2 からのエクスポートは、module1's セッション状態の最上位に配置されます。 を使用する場合、 Import-Module -Scope local
エクスポートは最上位レベルではなく現在のスコープオブジェクトに配置されます。 _モジュール_を使用していて、 Import-Module -Scope global
(または) を使用して Import-Module -Global
別のモジュールを読み込む場合、そのモジュールとそのエクスポートは、モジュールのローカルセッション状態ではなく、グローバルセッション状態に読み込まれます。 この機能は、モジュールを操作するモジュールを作成するように設計されています。 WindowsCompatibility モジュールは、プロキシモジュールをグローバルスコープにインポートするためにこれを行います。
入れ子になったプロンプト
同様に、入れ子になったプロンプトには独自のスコープがありません。 入れ子になったプロンプトを入力すると、入れ子になったプロンプトは環境のサブセットになります。 ただし、ローカルスコープ内にとどまります。
スクリプトには独自のスコープがあります。 スクリプトをデバッグしているときに、スクリプト内のブレークポイントに近づいた場合は、スクリプトのスコープを入力します。
プライベートオプション
エイリアスと変数には、 Privateという値を取ることができるオプションプロパティがあります。 プライベートオプションを持つアイテムは、作成されたスコープ内で表示および変更できますが、スコープ外で表示または変更することはできません。
たとえば、グローバルスコープでプライベートオプションを持つ変数を作成し、スクリプトを実行すると、 Get-Variable
スクリプト内のコマンドにプライベート変数は表示されません。 このインスタンスでグローバルスコープ修飾子を使用しても、プライベート変数は表示されません。
、、、およびコマンドレットの option パラメーターを使用して、 New-Variable
Set-Variable
New-Alias
Set-Alias
option プロパティの値を Private に設定できます。
表示
変数またはエイリアスの可視性プロパティによって、コンテナーの外側に項目が作成されたことを確認できるかどうかが決まります。 コンテナーには、モジュール、スクリプト、またはスナップインを使用できます。 可視性は、 Optionプロパティのプライベート値がスコープ向けに設計されているのと同じ方法でコンテナー用に設計されています。
可視性プロパティは、パブリックとプライベートの値を受け取ります。 プライベート可視性を持つアイテムは、そのアイテムが作成されたコンテナー内でのみ表示および変更できます。 コンテナーを追加またはインポートした場合、プライベート可視性を持つアイテムを表示または変更することはできません。
可視性はコンテナー用に設計されているため、スコープでは異なる方法で動作します。
- グローバルスコープでプライベート可視性を持つアイテムを作成した場合、そのアイテムを表示または変更することはできません。
- プライベート可視性を持つ変数の値を表示または変更しようとすると、PowerShell によってエラーメッセージが返されます。
およびコマンドレットを使用して、 New-Variable
Set-Variable
プライベート可視性を持つ変数を作成できます。
使用例
例 1: スクリプト内の変数の値のみを変更する
次のコマンドは、スクリプト内の変数の値を変更し $ConfirmPreference
ます。 この変更はグローバルスコープには影響しません。
最初に、ローカルスコープの変数の値を表示するには、 $ConfirmPreference
次のコマンドを使用します。
PS> $ConfirmPreference
High
次のコマンドを含む Scope.ps1 スクリプトを作成します。
$ConfirmPreference = "Low"
"The value of `$ConfirmPreference is $ConfirmPreference."
スクリプトを実行します。 スクリプトによって変数の値が変更され、 $ConfirmPreference
スクリプトスコープでその値が報告されます。 出力は次のようになります。
The value of $ConfirmPreference is Low.
次に、現在のスコープ内の変数の現在の値をテストし $ConfirmPreference
ます。
PS> $ConfirmPreference
High
この例は、スクリプトスコープ内の変数の値を変更しても、親スコープ内の変数の値には影響しないことを示しています。
例 2: 異なるスコープの変数値を表示する
スコープ修飾子を使用して、ローカルスコープおよび親スコープ内の変数の値を表示できます。
まず、 $test
グローバルスコープで変数を定義します。
$test = "Global"
次に、変数を定義する Sample.ps1 スクリプトを作成し $test
ます。 スクリプトでは、スコープ修飾子を使用して、変数のグローバルバージョンまたはローカルバージョンのいずれかを参照し $test
ます。
Sample.ps1:
$test = "Local"
"The local value of `$test is $test."
"The global value of `$test is $global:test."
Sample.ps1 を実行すると、出力は次のようになります。
The local value of $test is Local.
The global value of $test is Global.
スクリプトが完了すると、のグローバル値のみ $test
がセッションで定義されます。
PS> $test
Global
例 3: 親スコープ内の変数の値を変更する
プライベートオプションや別の方法を使用して項目を保護しない限り、親スコープ内の変数の値を表示および変更できます。
まず、 $test
グローバルスコープで変数を定義します。
$test = "Global"
次に、変数を定義する Sample.ps1 スクリプトを作成し $test
ます。 スクリプトでは、スコープ修飾子を使用して、変数のグローバルバージョンまたはローカルバージョンのいずれかを参照し $test
ます。
Sample.ps1:
$global:test = "Local"
"The global value of `$test is $global:test."
スクリプトが完了すると、のグローバル値 $test
が変更されます。
PS> $test
Local
例 4: プライベート変数の作成
プライベート変数は、value がprivateであるオプションプロパティを持つ変数です。 プライベート変数は子スコープによって継承されますが、作成されたスコープ内でのみ表示または変更できます。
次のコマンドは、ローカルスコープ内にというプライベート変数を作成し $ptest
ます。
New-Variable -Name ptest -Value 1 -Option private
ローカルスコープのの値を表示および変更でき $ptest
ます。
PS> $ptest
1
PS> $ptest = 2
PS> $ptest
2
次に、次のコマンドを含む Sample.ps1 スクリプトを作成します。 コマンドは、の値を表示して変更しようとし $ptest
ます。
Sample.ps1:
"The value of `$Ptest is $Ptest."
"The value of `$Ptest is $global:Ptest."
$ptest
変数はスクリプトスコープに表示されません。出力は空です。
"The value of $Ptest is ."
"The value of $Ptest is ."
例 5: リモートコマンドでローカル変数を使用する
ローカルセッションで作成されたリモートコマンドの変数については、スコープ修飾子を使用し Using
ます。 PowerShell では、リモートコマンドの変数がリモートセッションで作成されていることを前提としています。
の構文は次のとおりです。
$Using:<VariableName>
たとえば、次のコマンドは、 $Cred
ローカルセッションで変数を作成し、 $Cred
リモートコマンドでその変数を使用します。
$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}
Using スコープは、PowerShell 3.0 で導入されました。 PowerShell 2.0 で、変数がローカルセッションで作成されたことを示すには、次のコマンド形式を使用します。
$Cred = Get-Credential
Invoke-Command $s {
param($c)
Remove-Item .\Test*.ps1 -Credential $c
} -ArgumentList $Cred