関数

関数を使用すると、関係する処理をひとまとめにできます

構文

関数を使用する際は、事前に定義する必要があります。

# 関数
function [<scope:>] Name (Parameters) {
    statement_block
}
 
# フィルター
filter [<scope:>] Name (Parameters) {
    statement_block
}

パラメーターを受け取る関数を使用する際には、括弧はつけません。

returnステートメント

他の言語と同じように、returnをサポートしています。
ただし、以下の2つの記述はreturnステートメントの位置が異なりますが、等価です。

return $true
$true
return

exitステートメント

exitステートメントを使用することで、エラーを返すことができます。

exit errorlevel

パラメーターの指定方法

自動変数$args

自動変数$argsは、パラメーター名が指定されていないパラメーターを格納します。

function Double {
    foreach ($arg in $args) {
        $arg * 2
    }
}
PS> Double 2 3
4
6

パラメーター指定

パラメーターが必要な場合は、「FunctionName ($item1, $item2) {}」の形で記述します。

function Multiplication ($num) {
    Write-Host "num = $num, args = $args"
    foreach ($arg in $args) {
        $arg * $num
    }
}

パラメーターを指定する場合は「FunctionName -item1 param1 -item2 param2」と記述します。
パラメーター名を指定している場合は、順番を変更できます。
パラメーターを必要としている関数で、パラメーター名をしていていない場合は最初のパラメーターが割り当てられます。

PS> Multiplication -num 2 2 3
num = 2, args = 2 3
4
6
PS> Multiplication 2 3 -num 5
num = 5, args = 2 3
10
15
PS> Multiplication 2 3
num = 2, args = 3
6

paramステートメント

paramステートメントを使って、引数を定義できます。
paramステートメントは、スクリプト・関数・スクリプトブロックで使用できます。

LinkString.ps1

param([string]$text1, [string]$text2)
$text1 + $text2
PS> .\LinkString.ps1 aaa bbb
aaabbb

パラメーターの型とデフォルト値

パラメーターの型を指定する場合は、
[型名]$パラメーター名の形で記述します。

パラメーターのデフォルト値を指定する場合は、
$パラメーター名 = デフォルト値の形で記述します。

function GetString ([string]$text = "text", [int]$num = 3) {
    $text * $num
}
PS> GetString
texttexttext
PS> GetString One 1
One

型ショートカット

型には、完全なクラス名と簡略形とがあります。

  • [swich]:パラメーターを指定しない場合はFalse、指定する場合はTrueになる。
  • [ref]:参照渡し
  • [xml]:XML 他。

[switch]の挙動

動作の切り替えには[switch]を使うと便利です。

function TestSwitch ([switch]$param) {
    Write-Host $param
}
PS> TestSwitch
False
PS> TestSwitch -param
True

パラメーターを必須にする

パラメーターを必須にするには、[parameter(mandatory)]を使用します。

V3.0以降は、[Parameter(Mandatory)]

function SampleFunc ([Parameter(Mandatory)]$Param) {
    $Param
}

V2.0は、[Parameter(Mandatory=$True)]

function SampleFunc ([Parameter(Mandatory=$True)]$Param) {
    $Param
}

パラメーターを制限する

パラメーターを制限するには、VaridateSet()を使用します。
Tabキーによる入力補完もされるようになります。

パラメーターの値を、あらかじめ決められた一連の値のうちの1つに制限できます。
おまけに、Tabキーによる入力補完ができるようになります。

script

param(
    [validateset("Cyan","Magenta","Yellow","Black")]$cmyk = "Cyan",
    [validateset("Red","Green","Blue")]$rgb = "Red"
)
 
Write-Host $cmyk
Write-Host $rgb

実行例

PS> .\script.ps1 Black Blue # 「.ps1」の後に「スペース」+Tabキーで入力補完される
Black
Blue

パイプラインと関数

関数はパイプラインに組み込むこともできる。

自動変数$input

自動変数$inputには、パイプラインの(配列ではなく)列挙子が格納されます。
通常の配列と異なり、前の情報にアクセスすることができません。
$inputを配列として扱いたければ、@($input)として、強制的に配列化させる必要があります。
下記関数は「自動変数$args」の時とは、$inputの部分だけ異なります。

function Double {
    foreach ($arg in $input) { # この$input部分だけ異なる
        $arg * 2
    }
}

自動変数$argsの時とは異なり、パイプを使ってパラメーターを指定します。

PS> 2,3 | Double
4
6

非パイプライン用の関数の様にパラメーターを指定しても、
正常にパラメーターを受け取れず動作しません。

PS> Double 2,3
PS>

begin/process/endキーワード

begin/process/endキーワードを使用することで、初期化・レコード毎の処理・クリーンアップを明示することができる。
ここでは「処理順序」に注目したい。
begin/process/endキーワード内の処理順序は以下の通りです。

function BeginProcessEnd ($id) {
    begin {
        Write-Host "Begin (ID:$id)"
    }
    process {
        Write-Host "Process $_ (ID:$id)"
        $_
    }
    end {
        Write-Host "End (ID:$id)"
    }
}

処理順序は「Begin全部→パイプラインの要素を1つづつ処理→End全部」になります。

PS> 1,2 | BeginProcessEnd 1 | BeginProcessEnd 2 | BeginProcessEnd 3
Begin (ID:1)
Begin (ID:2)
Begin (ID:3)
Process 1 (ID:1)
Process 1 (ID:2)
Process 1 (ID:3)
1
Process 2 (ID:1)
Process 2 (ID:2)
Process 2 (ID:3)
2
End (ID:1)
End (ID:2)
End (ID:3)

filter

filterキーワードを使って、パイプライン用の関数を作れます。
filter内で自動変数$_$PSItemを使用できます。

# 偶数を取得する
filter GetEven {
    if (!($_ % 2)) {
        $_
    }
}
PS> 1..10 | GetEven
2
4
6
8
10

YouTube

動画による説明はこちら。

参考リンク

Chapter 9 - Functions | Microsoft Docs

About Functions | Microsoft Docs

About Return | Microsoft Docs


スポンサーリンク