PowerShell

【PowerShell】スクリプトと関数で使う引数の基本設定と活用ポイント

PowerShellでは、スクリプトや関数に柔軟な値を渡すために引数が活用されます。

スクリプトでは$argsを用い、関数ではparamブロックで各パラメーターを定義できます。

実行時に異なる値を適用することで、動作を自在に変更できるため、とても使いやすい機能です。

スクリプトでの引数利用

$args 配列の基本操作

引数の順序とインデックスによるアクセス

スクリプト実行時に渡された引数は、$args 配列に格納されます。

配列のインデックス番号を指定することで、各引数にアクセスできます。

例えば、最初の引数は $args[0]、次の引数は $args[1] と指定します。

下記のサンプルコードは、引数の順序を利用して値を表示する例です。

# sample.ps1

# コメント:スクリプトに渡された引数の順序に従い、値を表示しています。

Write-Host "First argument: $($args[0])"
Write-Host "Second argument: $($args[1])"
First argument: Hello
Second argument: World

可変引数の取り扱い方法

渡される引数の数が可変の場合、$args 配列全体をループ処理することで柔軟に対応できます。

以下の例では、渡されたすべての引数を順に出力しています。

# sample.ps1

# コメント:すべての引数を foreach ループで確認しています。

foreach ($arg in $args) {
    Write-Host "Argument: $arg"
}
Argument: Apple
Argument: Banana
Argument: Cherry

引数の数と受け渡しの注意点

スクリプトを実行する際、意図した引数の数が渡されていないとエラーや予期しない動作につながることがあります。

必要な引数が不足している場合は、以下のように引数の数をチェックする方法がおすすめです。

# sample.ps1

# コメント:引数の数が期待通りか確認し、不足している場合は使用方法の案内を表示します。

if ($args.Count -lt 2) {
    Write-Host "Usage: .\sample.ps1 <Argument1> <Argument2>"
    exit
}
Write-Host "Argument 1: $($args[0])"
Write-Host "Argument 2: $($args[1])"
Usage: .\sample.ps1 <Argument1> <Argument2>

関数での引数設定

paramブロックによる定義方法

関数内で引数を明示的に定義するには、param ブロックが便利です。

これにより、引数の型やデフォルト値、必須属性の設定が可能となります。

パラメーターの型指定

パラメータの型を指定することで、関数に渡す引数のデータ型を制限できます。

下記のサンプルコードは、[string]型の引数を受け取る関数の例です。

function Show-Message {
    param (
        [string]$Message
    )
    Write-Host "Message: $Message"
}

# コメント:関数呼び出しで文字列を指定しています。

Show-Message -Message "Hello PowerShell!"
Message: Hello PowerShell!

デフォルト値と必須属性の設定

引数にデフォルト値を設定することで、省略可能な値を柔軟に扱えます。

必須パラメーターには [Parameter(Mandatory=$true)] を設定することが可能です。

function Welcome {
    param (
        [Parameter(Mandatory=$true)]
        [string]$Name,
        [string]$Greeting = "Welcome"
    )
    Write-Host "$Greeting, $Name!"
}

# コメント:必須の引数 $Name を指定し、省略可能な $Greeting はデフォルト値が使用されます。

Welcome -Name "Alice"
Welcome, Alice!

複数引数の受け渡し方

関数には複数のパラメーターを同時に渡すことができます。

以下の例では、名前と年齢の2つの引数を受け取り、メッセージを表示します。

function Introduce {
    param (
        [string]$Name,
        [int]$Age
    )
    Write-Host "Hello, my name is $Name and I am $Age years old."
}

# コメント:引数を2つ指定した関数呼び出し例です。

Introduce -Name "Bob" -Age 25
Hello, my name is Bob and I am 25 years old.

スイッチパラメーターの利用

スイッチによるオプション指定の動作

スイッチパラメーターは、指定すると $true、省略すると $false の値を持つ便利なオプションです。

これにより、引数が存在するかどうかを簡単に確認できます。

function Shout-Message {
    param (
        [string]$Name,
        [switch]$Shout
    )
    if ($Shout) {
        Write-Host "HELLO, $Name!"
    }
    else {
        Write-Host "Hello, $Name."
    }
}

# コメント:$Shout を使って大文字の挨拶を制御しています。

Shout-Message -Name "Alice" -Shout
HELLO, Alice!

実際の活用事例

スイッチパラメーターは、ログ出力の詳細レベルやデバッグオプションなど、複数のシナリオで活用可能です。

以下の例は、詳細な出力を行うかどうかを切り替える関数です。

function Get-Data {
    param (
        [switch]$VerboseMode
    )
    Write-Host "データ取得を実行します。"
    if ($VerboseMode) {
        Write-Host "詳細情報:デバッグログや各種パラメーターの状態を表示します。"
    }
    else {
        Write-Host "通常モードでの実行です。"
    }
}

# コメント:詳細モードを有効にして、より多くの情報を表示する例です。

Get-Data -VerboseMode
データ取得を実行します。
詳細情報:デバッグログや各種パラメーターの状態を表示します。

パラメーター属性と検証の詳細設定

ValidateSetによる値の限定

引数に対して、許容する値のセットを指定するには、[ValidateSet()] 属性を利用します。

これにより、予期しない値が渡されることを防ぐ仕組みが構築できます。

許容値の定義方法

以下の例では、ユーザーの役割を “Admin”, “User”, “Guest” の中から選ぶように強制しています。

function Set-User {
    param (
        [Parameter(Mandatory=$true)]
        [string]$Username,
        [ValidateSet("Admin", "User", "Guest")]
        [string]$Role
    )
    Write-Host "設定中のユーザー: $Username"
    Write-Host "付与する役割: $Role"
}

# コメント:関数呼び出し時には、$Role に "Admin", "User", "Guest" のいずれかを指定する必要があります。

Set-User -Username "Charlie" -Role "Admin"
設定中のユーザー: Charlie
付与する役割: Admin

エラー発生時の通知設定

許容値以外の値を指定すると、PowerShell が自動的にエラーを出力します。

これにより、ユーザーは入力ミスにすばやく気づくことができます。

たとえば、下記の例では不正な値を指定するとエラーが表示されます。

# コメント:Role に不正な値を設定すると validation エラーが発生します。

Set-User -Username "Charlie" -Role "SuperAdmin"
Set-User : Cannot validate argument on parameter 'Role'. The argument "SuperAdmin" does not belong to the set "Admin,User,Guest" specified by the ValidateSet attribute.

カスタム検証の実装

検証ロジックの組み込み

場合によっては、ValidateSet では対処できない複雑な条件での検証が必要になることがあります。

その場合、ValidateScript を使ってカスタム検証ロジックを実装できます。

function Check-Numeric {
    param (
        [ValidateScript({ $_ -as [int] -ne $null })]
        [string]$InputValue
    )
    Write-Host "入力された数値は $InputValue です。"
}

# コメント:この関数は、引数が数値に変換できるかどうかを確認します。

Check-Numeric -InputValue "123"
入力された数値は 123 です。

エラーメッセージのカスタマイズ

ValidateScript 内でエラーメッセージをカスタマイズする場合、条件に合致しない場合に適切なエラー出力を行う工夫が可能です。

以下にサンプルコードを示します。

function Verify-Range {
    param (
        [ValidateScript({
            if ($_ -ge 1 -and $_ -le 10) {
                $true
            }
            else {
                throw "値は1から10の範囲で指定してください。"
            }
        })]
        [int]$Number
    )
    Write-Host "入力された数値: $Number"
}

# コメント:範囲外の値を指定すると、カスタムエラーメッセージが表示されます。

Verify-Range -Number 15
Verify-Range : 値は1から10の範囲で指定してください。

高度な引数設定と応用

Dynamic Parameter の活用

実行時に変化するパラメーターの定義

Dynamic Parameter を利用すると、実行時の条件に合わせたパラメーターの提供ができます。

下記の例は、実行環境に応じたパラメーターを動的に追加する方法を示しています。

function Invoke-DynamicParam {
    [CmdletBinding()]
    param ()
    Dynamicparam {

        # コメント:DynamicParameterDictionary の作成

        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $parameterAttribute = New-Object System.Management.Automation.ParameterAttribute
        $parameterAttribute.Mandatory = $true
        $attributeCollection.Add($parameterAttribute)

        # コメント:DynamicParameter の定義

        $runtimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter("DynamicValue", [string], $attributeCollection)
        $paramDictionary.Add("DynamicValue", $runtimeParam)
        return $paramDictionary
    }
    Write-Host "DynamicValue の値: $($PSBoundParameters['DynamicValue'])"
}

# コメント:実行時に DynamicValue パラメーターが必須となります。

Invoke-DynamicParam -DynamicValue "Dynamic Test"
DynamicValue の値: Dynamic Test

配列・ハッシュテーブルでの引数利用

複雑なデータ構造の受け渡し

複雑なデータを関数に渡す場合、配列やハッシュテーブルを利用するのも効果的です。

下記のサンプルは、複数の値をまとめたハッシュテーブルを引数として受け取り、各キーと値を表示するコードです。

function Show-UserInfo {
    param (
        [hashtable]$UserInfo
    )
    Write-Host "ユーザー情報:"
    foreach ($key in $UserInfo.Keys) {
        Write-Host "$key : $($UserInfo[$key])"
    }
}

# コメント:ハッシュテーブルを作成して、関数に渡しています。

$userData = @{
    "Name" = "Diana"
    "Age" = 28
    "Role" = "User"
}
Show-UserInfo -UserInfo $userData
ユーザー情報:
Name : Diana
Age : 28
Role : User

オブジェクトとしての引数設定

プロパティベースのパラメーター利用

オブジェクトをパラメータとして使用する場合、オブジェクトのプロパティを直接利用できます。

下記の例では、カスタムオブジェクトのプロパティを利用して詳細情報を出力する方法を示します。

function Display-Product {
    param (
        [Parameter(Mandatory=$true)]
        [PSCustomObject]$Product
    )
    Write-Host "製品名: $($Product.Name)"
    Write-Host "価格: $($Product.Price)"
    Write-Host "在庫状況: $($Product.InStock)"
}

# コメント:製品情報を含むカスタムオブジェクトを作成しています。

$productObject = [PSCustomObject]@{
    Name    = "Laptop"
    Price   = 1500
    InStock = $true
}
Display-Product -Product $productObject
製品名: Laptop
価格: 1500
在庫状況: True

引数処理に関するトラブルシューティング

型エラーと不正値への対処

型チェックとエラーメッセージの確認

関数やスクリプトで定義した型と実際に渡された引数の型が一致しない場合、エラーが発生する可能性があります。

適切な型チェックを行い、エラーメッセージを確認することで、問題の特定と解決が可能となります。

例えば、数値型として定義したパラメーターに文字列が渡された場合、以下のようなエラーが出力されます。

function Process-Number {
    param (
        [int]$Number
    )
    Write-Host "受け取った数値: $Number"
}

# コメント:意図せず文字列を渡した例です。エラーが発生します。

Process-Number -Number "NotANumber"
Process-Number : Cannot convert value "NotANumber" to type "System.Int32".

入力値の事前検証手法

例外発生防止の工夫と設定変更方法

入力値の検証を事前に実施することで、例外発生を防ぐ工夫が求められます。

try...catch 構文や事前チェックを組み合わせることで、ユーザーに親切なエラーメッセージを返す仕組みが構築できます。

下記のサンプルでは、入力値の検証とエラー処理をシンプルに実装しています。

function Safe-Convert {
    param (
        [string]$InputValue
    )
    try {

        # コメント:強制的に整数型に変換を試みます。

        $number = [int]$InputValue
        Write-Host "変換成功:$number"
    }
    catch {
        Write-Host "エラー:入力値 '$InputValue' は数値に変換できません。"
    }
}

# コメント:正しい数値の場合と、変換できない場合の両方をテストします。

Safe-Convert -InputValue "100"
Safe-Convert -InputValue "abc"
変換成功:100
エラー:入力値 'abc' は数値に変換できません。

まとめ

これまで、スクリプトでの引数利用から関数での詳細な設定、さらに動的なパラメーターや複雑なデータ構造の受け渡しの方法まで、柔軟に引数を扱う方法について説明してきました。

各テクニックを組み合わせることで、現場のニーズに合った柔軟なコードが書けるようになると思います。

この記事を参考に、日々のスクリプト作成を進めていただければ幸いです。

関連記事

Back to top button