PowerShell スクリプトモジュールを試す

PowerShell でモジュールを作ったことがなかったので試してみました。PowerShell のモジュールとしては C# で書くバイナリモジュールとPowerShell で書くスクリプトモジュールがありますが、今回の対象はスクリプトモジュールです。

とりあえずこんな感じで Main.ps1Greeting.psm1 を配置しました。

ModuleSample
    │   Main.ps1
    │
    └───Modules
        └───Greeting
                Greeting.psm1

Greeting.psm1スクリプトモジュールの本体です。とりあえず 1 個関数を書いておきます。

function Get-Hello {
    Write-Output "Hello World!"
}

呼出し側 Main.ps1 では Import-Module でモジュールを読み込みます。

Import-Module .\Modules\Greeting

Get-Hello

実行結果です。

> .\Main.ps1
Hello World!

Import-Module の代わりに using module を使ってモジュールを読み込むこともできます。

using module .\Modules\Greeting

Get-Hello

フォルダーを指定してモジュールを読み込む場合はフォルダー名(Greeting)とファイル名(Greeting.psm1)が同じである必要があります。フォルダー名と異なる場合でもファイル名を直接指定して読み込むことはできます。

using module .\Modules\Greeting\Greeting.psm1

Get-Hello

Export-ModuleMember を使うことで指定した関数だけをエクスポートすることができます。

function Get-Hello {
    Write-Output "Hello World!"
}

function Get-GoodMorning {
    Write-Output "Good Morning World!"
}

function  Get-GoodAfternoon {
    Write-Output "Good Afternoon World!"
}

function Get-GoodEvening {
    Write-Output "Good Evening World!"
}

function Get-GoodNight {
    Write-Output "Good Night World!"
}

$functionsToExport = @(
    "Get-Hello"
    "Get-GoodMorning"
    "Get-GoodAfternoon"
    "Get-GoodEvening"
)

Export-ModuleMember -Function $functionsToExport

Main.ps1 を以下のように書き換えておきます。

using module .\Modules\Greeting

Get-Hello
Get-GoodMorning
Get-GoodAfternoon
Get-GoodEvening
Get-GoodNight

モジュールを読み込みなおすために Remove-Module で読み込んだモジュールをいったん削除してから実行すると、エクスポートしなかった関数だけ実行に失敗します。

> Remove-Module Greeting
> .\Main.ps1
Hello World!
Good Morning World!
Good Afternoon World!
Good Evening World!
Get-GoodNight : 用語 'Get-GoodNight' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。

間違った挨拶をしないように、時間に応じた挨拶を返す Get-Greeting を定義して他の関数は非公開にしてみました。

function Get-Hello {
    Write-Output "Hello World!"
}

function Get-GoodMorning {
    Write-Output "Good Morning World!"
}

function  Get-GoodAfternoon {
    Write-Output "Good Afternoon World!"
}

function Get-GoodEvening {
    Write-Output "Good Evening World!"
}

function Get-GoodNight {
    Write-Output "Good Night World!"
}

function Get-Greeting {
    param (
        [DateTime]$DateTime = (Get-Date)
    )

    if ($DateTime.Hour -lt 5) {
        Get-GoodNight
        return
    }

    if ($DateTime.Hour -lt 12) {
        Get-GoodMorning
        return
    }

    if ($DateTime.Hour -lt 18) {
        Get-GoodAfternoon
        return
    }

    if ($DateTime.Hour -lt 24) {
        Get-GoodEvening
        return
    }
}

$functionsToExport = @(
    "Get-Hello"
    "Get-Greeting"
)

Export-ModuleMember -Function $functionsToExport