PowerShell モジュールで変数をエクスポートするときの挙動について
はじめに
PowerShell モジュールで変数をエクスポートするときの挙動について、ちょっとハマりどころがあったので、整理してみたいと思います。
スクリプトで Export-ModuleMember を呼び出さない場合
まずは Export-ModuleMember
を呼び出さない場合を見てみます。HelloWorld.psm1
という名前でファイルを作成し、各スコープごとに変数を宣言します。
$private:HelloWorldPrivate = 'HelloWorld'
$local:HelloWorldLocal = 'HelloWorld'
$script:HelloWorldScript = 'HelloWorld'
$global:HelloWorldGlobal = 'HelloWorld'
このモジュールを読み込んだときに使用できる変数は以下のようになります。
PS C:\> Import-Module .\HelloWorld.psm1
PS C:\> Get-ChildItem variable: | where Name -like 'HelloWorld*'
Name Value
---- -----
HelloWorldGlobal HelloWorld
global
スコープで宣言した変数以外は使用できないことがわかります。
スクリプトで Export-ModuleMember を呼び出す場合
先ほどの HelloWorld.psm1
を少しいじって Export-ModuleMember
を追加します。
$private:HelloWorldPrivate = 'HelloWorld'
$local:HelloWorldLocal = 'HelloWorld'
$script:HelloWorldScript = 'HelloWorld'
$global:HelloWorldGlobal = 'HelloWorld'
Export-ModuleMember -Variable '*'
同じようにモジュールを読み込みます。
PS C:\> Import-Module .\HelloWorld.psm1
PS C:\> Get-ChildItem variable: | where Name -like 'HelloWorld*'
Name Value
---- -----
HelloWorldGlobal HelloWorld
HelloWorldLocal HelloWorld
HelloWorldPrivate HelloWorld
HelloWorldScript HelloWorld
すべてのスコープについて変数がエクスポートされていることがわかります。
マニフェストで VariablesToExport を指定しない場合
スクリプト ファイル (.psm1
) を直接モジュールとして読み込むのではなく、マニフェスト ファイル (.psd1
) を使うことがほとんどだと思いますので、こちらの動作もみてみます。まずは VariablesToExport
を指定しない、つまり空の配列を指定した状態で試してみます。
@{
RootModule = 'HelloWorld.psm1'
ModuleVersion = '1.0'
VariablesToExport = @()
}
この状態でモジュールを読み込みます。
PS C:\> Import-Module .\HelloWorld.psd1
PS C:\> Get-ChildItem variable: | where Name -like 'HelloWorld*'
Name Value
---- -----
HelloWorldGlobal HelloWorld
Export-ModuleMember
と同様に global
スコープで宣言した変数のみが使用できます。
マニフェストで VariablesToExport を指定した場合
それでは VariablesToExport
を指定してみます。
@{
RootModule = 'HelloWorld.psm1'
ModuleVersion = '1.0'
VariablesToExport = '*'
}
同様にモジュールを読み込みます。
PS C:\> Import-Module .\HelloWorld.psd1
PS C:\> Get-ChildItem variable: | where Name -like 'HelloWorld*'
Name Value
---- -----
HelloWorldGlobal HelloWorld
Export-ModuleMember
のときとは違って、global
以外の変数がエクスポートされていません。
おわりに
一通り試してみて以下のことがわかりました。
-
Export-ModuleMember
を呼び出さなくてもglobal
スコープの変数は使用できる -
Export-ModuleMember
を呼び出すとどのスコープでも変数はエクスポートされる - マニフェストの
VariablesToExport
は無視される
じゃあ VariablesToExport
は何をするんだって話。バイナリ モジュールでも変数をエクスポートすることはできないので謎は深まります。いずれにしても変数をエクスポートする場合は明示的に Export-ModuleMember
を呼び出しましょう。
Discussion