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