変数のスコープ
まずは、下記スクリプトで変数のスコープについてみていきたいと思います。
$a = 3
function Sample1
{
Write-Host "1)変数`$a=$a"
$a = 5
Write-Host "2)変数`$a=$a"
}
#関数 sample1を実行
Sample1
Write-Host "3)変数`$a=$a"
このスクリプトを実行すると結果は下記のようになります。
PS C:\Work> ./Scope1.ps1 1)変数$a=3 2)変数$a=5 3)変数$a=3
この動作について図で解説します。

スクリプトの1行目で変数$aを作成し、3を代入しています。この変数はスクリプト内で有効です(1行目から12行目までがこの変数のスコープ。スクリプトスコープという)。
次に、11行目で関数Sample1を呼び出します。この呼び出しにより5行目が実行され、ここの変数$aでは1行目で代入した値「3」が表示されます。
次に6行目で変数$aに「5」を代入していますが、この変数$aは1行目で作成した変数とは別のものです。関数Sample1内でのみ有効で、生存期間は6行目から7行目までとなります。これをローカル変数と呼びます。
関数Sample1の実行が終わり、最後に12行目が実行されるわけですが、ここの変数$aは1行目で作成した変数$aであり、結果として「3」が表示されます。
以上より、次のことが分かります。
- 関数の外側で作成した変数は、スクリプトファイル内すべてが有効範囲である。
- 関数内で作成した変数は、関数内のみが有効範囲である。
- 関数の外で作成された変数と、関数内で作成した変数が同一名の場合は関数内で作成した変数が優先されるが、スクリプトスコープを持つ変数を上書きしない。
スクリプトスコープを持つ変数を参照する
先ほどの例で、$aという同じ名前でスコープの異なる2つの変数を使用しました。関数内でローカル変数$aが優先されることは説明したとおりです。
では、ローカル変数$aが優先されている状況下の中で、スクリプトスコープを持つ$aを参照するにはどうすれば良いでしょうか? この場合は、script修飾子を使用します。
例を示します。
$a = 3
function Sample2
{
Write-Host "1)変数`$a=$a"
$a = 5
Write-Host "2)変数`$a=$a"
Write-Host "3)変数`$a=$script:a"
$script:a = 7
Write-Host "4)変数`$a=$script:a"
Write-Host "5)変数`$a=$a"
}
#関数 sample2を実行
Sample2
Write-Host "6)変数`$a=$a"
このスクリプトの実行結果は下記の通りです。
PS C:\Work> ./Scope2.ps1 1)変数$a=3 2)変数$a=5 3)変数$a=3 4)変数$a=7 5)変数$a=5 6)変数$a=7
このように変数名が重複する場合に、スクリプトスコープを持つ変数を参照するには、$script:aと、キーワードscriptを付加し、スクリプトスコープの変数への参照であることを明示します。
また、スクリプトスコープの変数へ値を代入してもローカル変数の値は影響を受けないこと、関数を抜けた後の変数の値が変更されていることも確認してください。
ポイントは次の2点です。
- 関数内でスクリプトスコープを持つ変数へのアクセスは
script修飾子を使用する。 script修飾子を使用して値を書き換えても、同一名称のローカル変数へは影響しない。
少し複雑なサンプルですが、ぜひ実際に実行して、ローカル変数とスクリプトスコープを持つ変数の違いを理解してください。
