11 KiB
11 KiB
| applyTo | description |
|---|---|
| **/*.ps1,**/*.psm1 | Microsoftガイドラインに基づくPowerShellコマンドレットとスクリプトのベストプラクティス |
PowerShellコマンドレット開発ガイドライン
このガイドは、GitHub Copilotが慣用的で安全で保守可能なスクリプトを生成するのに役立つPowerShell固有の指示を提供します。MicrosoftのPowerShellコマンドレット開発ガイドラインと整合性を保っています。
命名規則
-
動詞-名詞形式:
- 承認されたPowerShell動詞を使用する(Get-Verb)
- 単数形の名詞を使用する
- 動詞と名詞の両方にPascalCaseを使用する
- 特殊文字とスペースを避ける
-
パラメーター名:
- PascalCaseを使用する
- 明確で説明的な名前を選択する
- 常に複数でない限り単数形を使用する
- PowerShell標準名に従う
-
変数名:
- パブリック変数にはPascalCaseを使用する
- プライベート変数にはcamelCaseを使用する
- 省略形を避ける
- 意味のある名前を使用する
-
エイリアスの回避:
- 完全なコマンドレット名を使用する
- スクリプトでエイリアスを使用しない(例:gciの代わりにGet-ChildItemを使用)
- カスタムエイリアスを文書化する
- 完全なパラメーター名を使用する
例
function Get-UserProfile {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Username,
[Parameter()]
[ValidateSet('Basic', 'Detailed')]
[string]$ProfileType = 'Basic'
)
process {
# ロジックをここに記述
}
}
パラメーター設計
-
標準パラメーター:
- 共通パラメーター名を使用する(
Path、Name、Force) - 組み込みコマンドレット規約に従う
- 専門用語にはエイリアスを使用する
- パラメーターの目的を文書化する
- 共通パラメーター名を使用する(
-
パラメーター名:
- 常に複数でない限り単数形を使用する
- 明確で説明的な名前を選択する
- PowerShell規約に従う
- PascalCase形式を使用する
-
型選択:
- 一般的な.NET型を使用する
- 適切な検証を実装する
- 限定されたオプションにはValidateSetを検討する
- 可能な場合はタブ補完を有効にする
-
スイッチパラメーター:
- ブール型フラグには[switch]を使用する
- $true/$falseパラメーターを避ける
- 省略時はデフォルトで$falseとする
- 明確なアクション名を使用する
例
function Set-ResourceConfiguration {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Name,
[Parameter()]
[ValidateSet('Dev', 'Test', 'Prod')]
[string]$Environment = 'Dev',
[Parameter()]
[switch]$Force,
[Parameter()]
[ValidateNotNullOrEmpty()]
[string[]]$Tags
)
process {
# ロジックをここに記述
}
}
パイプラインと出力
-
パイプライン入力:
- 直接オブジェクト入力には
ValueFromPipelineを使用する - プロパティマッピングには
ValueFromPipelineByPropertyNameを使用する - パイプライン処理にはBegin/Process/Endブロックを実装する
- パイプライン入力要件を文書化する
- 直接オブジェクト入力には
-
出力オブジェクト:
- フォーマットされたテキストではなくリッチオブジェクトを返す
- 構造化データにはPSCustomObjectを使用する
- データ出力にWrite-Hostを避ける
- 下流コマンドレット処理を有効にする
-
パイプラインストリーミング:
- 一度に一つのオブジェクトを出力する
- ストリーミングにはprocessブロックを使用する
- 大きな配列の収集を避ける
- 即座の処理を有効にする
-
PassThruパターン:
- アクションコマンドレットではデフォルトで出力なしとする
- オブジェクトリターンには
-PassThruスイッチを実装する -PassThruで変更/作成されたオブジェクトを返す- ステータス更新にはverbose/warningを使用する
例
function Update-ResourceStatus {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]$Name,
[Parameter(Mandatory)]
[ValidateSet('Active', 'Inactive', 'Maintenance')]
[string]$Status,
[Parameter()]
[switch]$PassThru
)
begin {
Write-Verbose "リソースステータス更新プロセスを開始します"
$timestamp = Get-Date
}
process {
# 各リソースを個別に処理
Write-Verbose "リソースを処理中: $Name"
$resource = [PSCustomObject]@{
Name = $Name
Status = $Status
LastUpdated = $timestamp
UpdatedBy = $env:USERNAME
}
# PassThruが指定された場合のみ出力
if ($PassThru) {
Write-Output $resource
}
}
end {
Write-Verbose "リソースステータス更新プロセスが完了しました"
}
}
エラーハンドリングと安全性
-
ShouldProcess実装:
[CmdletBinding(SupportsShouldProcess = $true)]を使用する- 適切な
ConfirmImpactレベルを設定する - システム変更には
$PSCmdlet.ShouldProcess()を呼び出す - 追加確認には
ShouldContinue()を使用する
-
メッセージストリーム:
-Verboseでの操作詳細にはWrite-Verbose- 警告条件には
Write-Warning - 非終了エラーには
Write-Error - 終了エラーには
throw - ユーザーインターフェーステキスト以外では
Write-Hostを避ける
-
エラーハンドリングパターン:
- エラー管理にはtry/catchブロックを使用する
- 適切なErrorAction設定を設定する
- 意味のあるエラーメッセージを返す
- 必要に応じてErrorVariableを使用する
- 適切な終了vs非終了エラーハンドリングを含める
-
非対話型設計:
- パラメーター経由で入力を受け入れる
- スクリプトで
Read-Hostを避ける - 自動化シナリオをサポートする
- すべての必要な入力を文書化する
例
function Remove-UserAccount {
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string]$Username,
[Parameter()]
[switch]$Force
)
begin {
Write-Verbose "ユーザーアカウント削除プロセスを開始します"
$ErrorActionPreference = 'Stop'
}
process {
try {
# 検証
if (-not (Test-UserExists -Username $Username)) {
Write-Error "ユーザーアカウント '$Username' が見つかりません"
return
}
# 確認
$shouldProcessMessage = "ユーザーアカウント '$Username' を削除"
if ($Force -or $PSCmdlet.ShouldProcess($Username, $shouldProcessMessage)) {
Write-Verbose "ユーザーアカウントを削除中: $Username"
# メイン操作
Remove-ADUser -Identity $Username -ErrorAction Stop
Write-Warning "ユーザーアカウント '$Username' が削除されました"
}
}
catch [Microsoft.ActiveDirectory.Management.ADException] {
Write-Error "Active Directoryエラー: $_"
throw
}
catch {
Write-Error "ユーザーアカウント削除の予期しないエラー: $_"
throw
}
}
end {
Write-Verbose "ユーザーアカウント削除プロセスが完了しました"
}
}
ドキュメントとスタイル
-
コメントベースヘルプ: パブリック向けの関数またはコマンドレットにはコメントベースヘルプを含める。関数内に
<# ... #>ヘルプコメントを追加し、少なくとも以下を含める:.SYNOPSIS簡潔な説明.DESCRIPTION詳細な説明.EXAMPLE実用的な使用法のセクション.PARAMETER説明.OUTPUTS返される出力の型.NOTES追加情報
-
一貫したフォーマット:
- 一貫したPowerShellスタイルに従う
- 適切なインデント(4スペース推奨)を使用する
- 文と同じ行に開始中括弧を配置
- 新しい行に終了中括弧を配置
- パイプライン演算子の後に改行を使用
- 関数とパラメーター名にPascalCaseを使用
- 不要な空白を避ける
-
パイプラインサポート:
- パイプライン関数にはBegin/Process/Endブロックを実装する
- 適切な場合はValueFromPipelineを使用する
- プロパティ名によるパイプライン入力をサポートする
- フォーマットされたテキストではなく適切なオブジェクトを返す
-
エイリアスを避ける: 完全なコマンドレット名とパラメーターを使用する
- スクリプトでエイリアスを使用しない(例:gciの代わりにGet-ChildItemを使用);エイリアスは対話型シェル使用では許可される。
?やwhereの代わりにWhere-Objectを使用%の代わりにForEach-Objectを使用lsやdirの代わりにGet-ChildItemを使用
完全な例:エンドツーエンドコマンドレットパターン
function New-Resource {
[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true)]
[ValidateNotNullOrEmpty()]
[string]$Name,
[Parameter()]
[ValidateSet('Development', 'Production')]
[string]$Environment = 'Development'
)
begin {
Write-Verbose "リソース作成プロセスを開始します"
}
process {
try {
if ($PSCmdlet.ShouldProcess($Name, "新しいリソースを作成")) {
# リソース作成ロジックをここに記述
Write-Output ([PSCustomObject]@{
Name = $Name
Environment = $Environment
Created = Get-Date
})
}
}
catch {
Write-Error "リソース作成に失敗しました: $_"
}
}
end {
Write-Verbose "リソース作成プロセスが完了しました"
}
}