PowerShellはWindowsで実行できるスクリプト言語です。タスクの自動化やシステム管理に役立ちます。そういったスクリプトは役に立ちますが、将来の自分などがスクリプトを改修する際に都度プログラムを細かく調べるのは手間です。よりそのスクリプトを理解、使用、改修しやすくするために、十分なヘルプ機能をつけておくことが望ましいです。この記事ではPowerShellスクリプトにいい感じのヘルプ機能を追加する方法を解説します。
ヘルプの実装例は次です。
<#
.SYNOPSIS
指定されたポート番号を使用しているプロセスを確認します。
.DESCRIPTION
このスクリプトは、指定されたポート番号を使用しているプロセスや、そのプロセスの実行ファイル名、
プロセスID、およびそのプロセスがサービスであるかどうかを確認するために使用されます。
.PARAMETER port
ポート番号を指定してください (0-65535)
.EXAMPLE
.\FindPortUsedProcess.ps1 8080
8080ポートを使用しているプロセスの情報を表示します。
#>
Param (
[Parameter(Mandatory=$true, Position=0, HelpMessage="ポート番号を指定してください")]
[ValidateScript({
# $port が '--help' または '/?' かどうかを確認する
if ($_ -eq '--help' -or $_ -eq '/?') {
return $true
}
# 数値に変換し、0 から 65535 の範囲にあるかどうかを確認する
$port = [UInt16]$_
if ($port -ge 0 -and $port -le 65535) {
return $true
}
# 範囲外の場合はエラーをスローする
throw "不正なポート番号: $_"
})]
[string]$port
)
# ヘルプを表示する
if ($port -eq '--help' -or $port -eq '/?') {
Get-Help $MyInvocation.InvocationName -Examples
return
}
###ここから先にコード本体###
PowerShellには Get-Help というヘルプ用のコマンドがあります。Get-Help はスクリプトを含む様々なモノのヘルプを呼び出すコマンドです。
Get-Help (Microsoft.PowerShell.Core) – PowerShell | Microsoft Learn
また Get-Help に読ませるためのスクリプトのコメントのフォーマットがあります。ソースコードの<#から#>までがそれです。詳しくは次リンクにあります。例のスクリプトでは概要である SYNOPSIS、詳細説明である DESCRIPTION、引数の説明である PARAMETER、使用例である EXAMPLE を入れています。これだけあればざっくりGet-Help [スクリプトファイル] --Examplesとされた時にヘルプとして整ったモノが表示されます。
コメントに基づくヘルプについて - PowerShell | Microsoft Learn
Get-Help というのは PowerShell の方言的なヘルプの呼び出し方です(自分が知らないだけで他言語にもあるやもしれませんが)。ヘルプを呼び出す際によくあるのは Linux 系の--helpとWindows系の/?です。例の中にある条件文は主にこれに対応するための部分です。 ValidateScript では引数を柔軟にバリデーションでき、Param 直後の早期リターンではこの場合はヘルプを表示するだけで終わるということを示せます。
ヘルプ用のコメントは手で作るのが少々煩雑です。これは ChatGPT などに任せると楽です。例えば次の様にしてコメントを追加できます。
次のPowerShellスクリプトに適したヘルプ用のコメントを追加してください ``` # ここにソースコード ```
例のソースコード全体
<#
.SYNOPSIS
指定されたポート番号を使用しているプロセスを確認します。
.DESCRIPTION
このスクリプトは、指定されたポート番号を使用しているプロセスや、そのプロセスの実行ファイル名、
プロセスID、およびそのプロセスがサービスであるかどうかを確認するために使用されます。
.PARAMETER port
ポート番号を指定してください (0-65535)
.EXAMPLE
.\FindPortUsedProcess.ps1 8080
8080ポートを使用しているプロセスの情報を表示します。
#>
Param (
[Parameter(Mandatory=$true, Position=0, HelpMessage="ポート番号を指定してください")]
[ValidateScript({
# $port が '--help' または '/?' かどうかを確認する
if ($_ -eq '--help' -or $_ -eq '/?') {
return $true
}
# 数値に変換し、0 から 65535 の範囲にあるかどうかを確認する
$port = [UInt16]$_
if ($port -ge 0 -and $port -le 65535) {
return $true
}
# 範囲外の場合はエラーをスローする
throw "不正なポート番号: $_"
})]
[string]$port
)
# ヘルプを表示する
if ($port -eq '--help' -or $port -eq '/?'-or $port -eq '!?') {
Get-Help $MyInvocation.InvocationName -Examples
return
}
# 指定されたポート番号を使用しているかどうかを確認する
# 使用されていないポートについていきなりプロセスIDを取得しようとするとエラーになるので、先に使用の有無を確認する
$isUsedPort = (Get-NetTCPConnection | Where-Object LocalPort -eq $port)
if ($isUsedPort -eq $null) {
Write-Host "$port ポートは使用されていません"
Exit 0
}
# 指定されたポート番号を使用しているプロセスIDを取得する
$pidL = (Get-NetTCPConnection -LocalPort $port).OwningProcess
if ($pidL -eq $null) {
Write-Host "$port ポートを使用しているプロセスはありません"
Exit 0
}
# プロセス実行ファイルの名前を取得する
$processName = (Get-Process -Id $pidL).Path
Write-Host "プロセスID: $pidL"
Write-Host "プロセス名: $processName"
# プロセスがサービスであるかどうかを確認する
$service = Get-WmiObject -Class Win32_Service | Where-Object { $_.PathName -eq $processName }
if ($service -ne $null) {
Write-Host "サービス名: $( $service.Name )"
} else {
Write-Host "サービスではありません"
}
