マイナビニュースマイナビ

PowerShell 7をシェルスクリプトとして使う - Get-Help対応

【連載】

PowerShell Core入門 - 基本コマンドの使い方

【第149回】PowerShell 7をシェルスクリプトとして使う - Get-Help対応

[2021/05/21 08:00]後藤大地 ブックマーク ブックマーク

前回までで、PowerShellスクリプトがかなり仕上がってきた。今回は、PowerShellに用意されている機能を使ってさらにPowerShell風のスクリプトに仕上げていこう。今回取り組むのは、Get-Help対応だ。

前回仕上げたスクリプト「test-d_13.ps1」は次の通りだ。引数の処理として「Param()」を使うように変更し、パラメータ指定時に補完機能が効くようになったことなどを確認した。

#!/usr/bin/env pwsh

#====================================================================
# 引数処理
#====================================================================
Param(
    [string]$DirectoryPath,
    [switch]$Help
)

if ($Help -Or -Not $DirectoryPath) {
    $scriptname = Split-Path -Leaf $PSCommandPath
    $errmsg = "usage: $scriptname " `
        + "[-DirectoryPath] ディレクトリパス " `
        + "[-Help]"
    Write-Error $errmsg
    exit 1
}

#====================================================================
# ディレクトリパスの存在確認処理
#====================================================================
if (Test-Path -PathType Container -Path $DirectoryPath) {
    # 指定されたパスはディレクトリであり、存在している。
    $True
} else {
    # 指定されたパスはディレクトリではない。
    if (Test-Path -PathType Leaf -Path $DirectoryPath) {
        # 指定されたパスはファイル。
        $infomsg = "$DirectoryPath : " `
            + "ファイルです。"
    } else {
        # 指定されたパスは存在しない。
        $infomsg = "$DirectoryPath : " `
            + "そのようなディレクトリは存在しません。"
    }
    Write-Host $infomsg
    $False
}

このスクリプトでは-Helpパラメータでスクリプトの簡単な使い方が表示されるようにしたわけだが、この書き方だとGet-Helpコマンドレットは次のように本当に最小限の出力しか行わない。

「Get-Help」を使ったときの出力

PowerShellでは、Get-Helpコマンドレットを使うことで、ほかのコマンドレットやモジュール、関数などのマニュアル(ヘルプ)を表示させることができる仕組みになっている。これはスクリプトにおいても同様で、「Get-Help」で使用できるようにヘルプを書いておけば、Get-Helpコマンドレットでもっときちんとした出力が行われるようになる。今回は、この部分の書き換えを行っていく。

「Get-Help」に対応したヘルプの書き方

スクリプトの場合、スクリプトが始まった直後に規定のフォーマットのコメントを書くことが「Get-Help」に対応する方法になっている。フォーマットは非常にシンプルなroffのようなもので、例えば次のように書けばよい。

<#
.SYNOPSIS

Adds a file name extension to a supplied name.

.DESCRIPTION

Adds a file name extension to a supplied name.
Takes any strings for the file name or extension.

.PARAMETER Name
Specifies the file name.

.PARAMETER Extension
Specifies the extension. "Txt" is the default.

.INPUTS

None. You cannot pipe objects to Add-Extension.

.OUTPUTS

System.String. Add-Extension returns a string with the extension
or file name.

.EXAMPLE

PS> extension -name "File"
File.txt

.EXAMPLE

PS> extension -name "File" -extension "doc"
File.doc

.EXAMPLE

PS> extension "File" "doc"
File.doc

.LINK

http://www.fabrikam.com/extension.html

.LINK

Set-Item
#>

上記サンプルは、次のドキュメントに掲載されているものだ。


基本的に「Get-Help」に対応したヘルプの書き方は上記のドキュメントにまとまっているので、これを参考にして書けばよい。

「.(ピリオド)」から始まっている大文字で記述された行は「キーワード」と呼ばれ、ヘルプで言うところの「セクションタイトル」に相当する。キーワードに続く行がそのセクションの内容だ。今作成しているスクリプトについて「Get-Help」に対応したコメントを書くとすれば、次のような感じになるだろう。

<# 
.SYNOPSIS
ディレクトリパスが存在するかどうかを判定。

.DESCRIPTION
指定されたパスがディレクトリパスであり、かつ、存在するかどうかを判定する。

.PARAMETER DirectoryPath
ディレクトリパスを指定。

.PARAMETER Help
ヘルプメッセージを表示。

.INPUTS
なし。パイプには対応していない。

.OUTPUTS
System.Boolean。ディレクトリパスが存在する場合にTrue、そうでない場合にFalse。

.EXAMPLE
PS> .\test-d .\Documents\
True

.EXAMPLE
PS> .\test-d .\Documents-non-exists\
False

.LINK
Test-Path
#>

キーワードには次のようなものが用意されている。

キーワード 内容
.SYNOPSIS スクリプトの簡単な説明。1回だけ使用可能
.DESCRIPTION スクリプトの詳しい説明。1回だけ使用可能
.PARAMETER パラメータ名 パラメータの説明
.EXAMPLE サンプルを記述
.INPUTS パイプラインで接続できるオブジェクトの.NET型
.OUTPUTS 出力されるオブジェクトの.NET型
.NOTES スクリプトの追加情報
.LINK 関連するトピックやURI
.FORWARDHELPTARGETNAME コマンド名 指定したコマンドのヘルプへリダイレクト
.FORWARDHELPCATEGORY カテゴリ Alias、Cmdlet、HelpFile、Function、Provider、General、FAQ、Glossary、ScriptCommand、ExternalScript、Filter、All
.REMOTEHELPRUNSPACE PSSession値 ヘルプトピックを含むセッションを指定
.EXTERNALHELP XMLヘルプファイル XMLベースヘルプファイル

表のキーワードは上のものほどよく使うもので、下にいくほどあまり使われないものになっている。「Get-Help」に対応したコメントはスクリプトの仕様書としても使えるものだ。スクリプトを書くときは最初にこのコメントを書き、その通りに動作するようにスクリプトを仕上げていくというのが書き方の一つにもなる。

「Get-Help」に対応させたスクリプト

では、「Get-Help」に対応させたスクリプトに書き換えてみよう。今回書き換えたスクリプト「test-d_14.ps1」は次の通りだ。

#!/usr/bin/env pwsh

<# 
.SYNOPSIS
ディレクトリパスが存在するかどうかを判定。

.DESCRIPTION
指定されたパスがディレクトリパスであり、かつ、存在するかどうかを判定する。

.PARAMETER DirectoryPath
ディレクトリパスを指定。

.PARAMETER Help
ヘルプメッセージを表示。

.INPUTS
なし。パイプには対応していない。

.OUTPUTS
System.Boolean。ディレクトリパスが存在する場合にTrue、そうでない場合にFalse。

.EXAMPLE
PS> .\test-d .\Documents\
True

.EXAMPLE
PS> .\test-d .\Documents-non-exists\
False

.LINK
Test-Path
#>

#====================================================================
# 引数
#====================================================================
Param(
    [string]$DirectoryPath,     # ディレクトリを指定
    [switch]$Help           # ヘルプを表示
)

if ($Help -Or -Not $DirectoryPath) {
    Get-Help $PSCommandPath
    exit 1
}

#====================================================================
# ディレクトリパスの存在確認
#====================================================================
if (Test-Path -PathType Container -Path $DirectoryPath) {
    # 指定されたパスはディレクトリであり、存在している。
    $True
} else {
    # 指定されたパスはディレクトリではない。
    if (Test-Path -PathType Leaf -Path $DirectoryPath) {
        # 指定されたパスはファイル。
        $infomsg = "$DirectoryPath : " `
            + "ファイルです。"
    } else {
        # 指定されたパスは存在しない。
        $infomsg = "$DirectoryPath : " `
            + "そのようなディレクトリは存在しません。"
    }
    Write-Host $infomsg
    $False
}

まず、動作から見てみよう。-Helpパラメータを指定する、もしくは引数を何も指定しないと「Get-Help」が内部で呼ばれるようにしてあるため、次のようにヘルプが表示される。

「Get-Help」によるヘルプの出力

直接「Get-Help」を使ってヘルプを表示させることもできる。先ほどと同じ出力が行われていることがわかるだろう。

「Get-Help」で明示的に行ったヘルプの出力

「Get-Help」にパラメータを指定すれば、より詳細なヘルプを表示させることもできる。

「Get-Help -Detailed」でより詳細なヘルプを表示させたところ

「Get-Help」に対応したコメントを追加しただけではなく、次のように-Helpパラメータを処理する部分も書き換えた。前回は、次のように自前で出力するメッセージ(usage)を作成し、それをWrite-Errorコマンドレットで出力させていた。

    $scriptname = Split-Path -Leaf $PSCommandPath
    $errmsg = "usage: $scriptname " `
        + "[-DirectoryPath] ディレクトリパス " `
        + "[-Help]"
    Write-Error $errmsg

今回は、この部分を次のように、内部でGet-Helpコマンドレットを呼ぶ処理へ変更している。

    Get-Help $PSCommandPath

スクリプトが「Get-Help」による出力に対応したのだから、内部から自分を指定して「Get-Help」を実行すれば-Helpパラメータの処理として使えるというわけだ。その分コードは短くなるし、重複する説明を書く必要もなくなり、スマートである。

これまで何度も説明しているように、スクリプトの処理そのものは「Test-Path」で指定されたパスがディレクトリかどうかを判定しているだけだ。しかし、スクリプトとして使えるように、PowerShellの流儀に従って整理していくと、結構なボリュームになってくる。最初にこの辺りをしっかり理解しておけば、今後のスクリプト作成がぐっと楽になるので、今のうちにこういった書き方はマスターしてしまおう。

参考資料

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

【連載】RPA入門 - ツールで学ぶ活用シーン

【連載】RPA入門 - ツールで学ぶ活用シーン

AIには、ルールベース、機械学習、深層学習(ディープラーニング)の3つのレベルがあり、レベルが上がるに連れてより高度な人工知能を実現しますが、AIのスピンオフという位置付けで、Digital Labor(仮想知的労働者)によるホワイトカラー業務の自動化を実現するRPAが注目されています。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で TECH+ の人気記事をお届けします
注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
Slackで始める新しいオフィス様式
Google Workspaceをビジネスで活用する
ニューノーマル時代のオウンドメディア戦略
ミッションステートメント
次世代YouTubeクリエイターの成長戦略
IoTでできることを見つけるための発想トレーニング
教えてカナコさん! これならわかるAI入門
AWSではじめる機械学習 ~サービスを知り、実装を学ぶ~
Kubernetes入門
SAFeでつくる「DXに強い組織」~企業の課題を解決する13のアプローチ~
マイクロサービス時代に活きるフレームワーク Spring WebFlux入門
AWSで作るマイクロサービス
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

会員登録(無料)

ページの先頭に戻る