はじめに
PowerShellのスクリプトモジュールをいくつか作ってみたことで、ある程度テンプレート構成がまとまったので記事にしてみます。
あくまで自分流のテンプレートなので「これが最適解」というものではなく、また今後も随時アップデートされていくと思うのでご了承ください。
スクリプトモジュールとは
PowerShellのモジュールについての詳しくて正確な情報はMicrosoftの公式ドキュメントに書いてありますが、この記事で扱う範囲について簡単に言えば関数ライブラリみたいなものと思っていただければ十分です。
psm1
形式のファイルに関数と Export-ModuleMember
コマンドを書いておき、それを Import-Module
コマンドで読み込むことで、既存のコマンドレットと同様に任意の場所(スクリプト内、コンソール上)で実行可能なコマンドを作ることができます。
スクリプトモジュールテンプレート
さっそくですが今回作ったテンプレートは下記のようなものです。
function TemplateModule {
<#
.SYNOPSIS
<コマンドの概要>
.DESCRIPTION
<コマンドの説明>
.PARAMETER Help|h
ヘルプを表示する
.PARAMETER <Parameter>
<Parameterの意味>
.PARAMETER CommonParameters
サポートしていません
.INPUTS
<入力の仕様>
.OUTPUTS
<出力の仕様>
.EXAMPLE
PS> TemplateModule
<コマンドのみ実行時の処理内容>
.EXAMPLE
PS> TemplateModule -Help
ヘルプを表示します
.EXAMPLE
PS> TemplateModule <Parameter>
<Parameter指定時の処理内容>
.LINK
参考: <参考サイト概要>
<URL>
#>
Param(
[Alias('h')][switch] $Help
)
if($Help){ Get-Help TemplateModule; return }
#------------------------------
# Main処理
#------------------------------
}
Export-ModuleMember -Function TemplateModule
# Aliasも設定してExportする場合
# Set-Alias <alias> TemplateModule
# Export-ModuleMember -Function TemplateModule -Alias <alias>
なお、このテンプレートを作るうえで以下のサイトを参考にさせていただきました。
http://www.vwnet.jp/Windows/PowerShell/SupportGetHelp.htm
https://docs.microsoft.com/ja-jp/powershell/scripting/developer/module/how-to-write-a-powershell-script-module
解説
全体構成
まず、スクリプトモジュールの全体構成としては関数定義とexportの2つになります。この辺はJavaScriptのexportと似ていますね。
exportがない場合はモジュールファイル内のすべての関数がexportされるので明示的に指定した方がよいでしょう。
ちなみに変数もexportできますが、変数の場合は明示的に指定したものとグローバル変数 ($global:hogehoge
) しかexportされないです。なのでモジュール内のトップレベルで変数を宣言しても影響はなさそうですね。
ヘルプコメント
関数の最初に書かれているやたら長いコメントブロックはヘルプドキュメントで、Get-Help
コマンドを実行したときに表示される内容です。
Get-Help
コマンドをオプションなしで実行したときはこの中の SYNOPSIS, DESCRIPTION, LINK 項目と自動生成の NAME, SYNTAX 項目しか表示されませんが、-Detailed
や -Full
をつけるとほかの情報も見ることができます。
また自動生成関連でいうと、自動生成される SYNTAX 項目は関数の Param()
を解析して自動で作ってくれますが、そこには CommonParameters というパラメータも追記されてしまいます。なのでパラメータ説明の1つにサポートしてない旨を注釈的に書いておくとよいと思います。(って参考サイトの筆者さんも言ってた)
ヘルプオプションの追加
せっかくヘルプを標準装備にしたのでヘルプを表示するオプションもテンプレートに加えてみました。
コマンドを実行する際に -Help
または '-h' で自コマンドに対して Get-Help
を実行するようにしました。
ほかにもパラメータが1つでも仕様にマッチしていなければヘルプに飛ばすという処理を入れてもいいかもしれないですね。
モジュールのImport
上記のテンプレートで作成したモジュールは Import-Module
コマンドで読み込むことができます。
ちなみに自分が開発中にハマった点として、モジュールの内容を更新して再読み込みさせたい場合は -Force
オプションをつけると上書きしてくれます。
VSCodeスニペット登録
上記のテンプレートを使うために毎回コピペをするのは面倒なので自分はVSCodeのスニペットに登録しました。
スニペットとは、例えばJavaファイルで sysout
と打つと System.out.println()
が入力されたり、HTMLファイルで html
と打つとHTMLのひな型が入力される機能のことです。
VSCodeでは言語ごとに自作のスニペットを追加できるのでPowerShellのスニペットに上記のテンプレートを追加してみました。
{
"PowerShell Module": {
"scope": "powershell",
"prefix": "module",
"body": [
"function $1 {",
" <#",
" .SYNOPSIS",
" <コマンドの概要>",
" ",
" .DESCRIPTION",
" <コマンドの説明>",
" ",
" .PARAMETER Help|h",
" ヘルプを表示する",
" ",
" .PARAMETER <PARAM>",
" <パラメータの説明>",
" ",
" .PARAMETER CommonParameters",
" サポートしていません",
" ",
" .INPUTS",
" <入力の仕様>",
" ",
" .OUTPUTS",
" <出力の仕様>",
" ",
" .EXAMPLE",
" PS> $1",
" <コマンドのみ実行時の処理内容>",
" ",
" .EXAMPLE",
" PS> $1 -Help",
" ヘルプを表示する",
" ",
" .EXAMPLE",
" PS> $1 <PARAM>",
" <パラメータを指定したときの処理内容>",
" ",
" .LINK",
" 参考: <参考サイト概要>",
" <URL>",
" #>",
" Param(",
" [Alias('h')][switch] $$Help",
" )",
" if($$Help){ Get-Help $1; return }",
"",
" #------------------------------",
" # Main処理",
" #------------------------------",
" $2",
"}",
"# 関数をそのままExportする場合",
"Export-ModuleMember -Function $1",
"",
"# Aliasも設定してExportする場合",
"# Set-Alias <alias> $1",
"# Export-ModuleMember -Function $1 -Alias <alias>",
""
],
"description": "PowerShell Module Template"
}
}
上記の内容を既存のPowerShellスニペットに追加するか、プロジェクトローカルのVSCode設定に上記設定ファイルを追加することで module
と入力して候補からテンプレートを1発で入力することができます。
関数名の部分を$1
で入力値を受け取るようにしているのでヘルプ内のExampleやExportコマンド部分にまとめて関数名を指定できます。
さいごに
今回はスクリプトモジュールを1ファイルにまとめて作成しましたが、モジュールマニフェストファイル(psd1
)にバージョンやExport範囲を指定する方法もあるみたいです。(むしろモジュールとしてはそちらのほうが標準セット?)
モジュールマニフェストも含めて作ることで PowerShell Gallery に公開して Install-Module
でインストール可能になるみたいです。(PythonでいうところのpipやJavaScriptでいうところのnpmみたいなものですかね)
その辺はこちらの記事が参考になりそうなのでいずれは自分も公開して記事にしたいですね。
最後に、今回作成したテンプレートを使って作ったいろいろなスクリプトモジュールをGitHubで公開しています。
あくまで自分が欲しい機能をモジュール化したものの詰め合わせなので万人に使えるかというと微妙ですが、興味があれば覗いてみてください。