関数
構文
関数を使用する際は、事前に定義する必要があります。
# 関数
function [<scope:>] Name (Parameters) {
statement_block
}
# フィルター
filter [<scope:>] Name (Parameters) {
statement_block
}
パラメーターを受け取る関数を使用する際には、括弧はつけません。
# ありそうな間違い例
$result = FunctionName($item1, $item2)
他のコマンドレットと同様扱うと覚えれば良いとおもいます。
# 正しい例
$result = FunctionName $item1 $item2
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
Note
Varidate系の属性は他にもいくつかあります。
- ValidateCount()
- ValidateNotNull()
- ValidateNotNullOrEmpty()
- ValidateLength()
- ValidatRange()
- ValidatePattern()
- ValidateScript()
パイプラインと関数
関数はパイプラインに組み込むこともできる。
自動変数$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
Note
- begin/process/endキーワードのないfunction = end部だけの関数
- filter = process部だけの関数。
けれど、要するにfunctionの機能限定版なので、積極的にfilterを使う必要ないかもしれません。
YouTube
動画による説明はこちら。
参考リンク
Chapter 9 - Functions | Microsoft Docs
About Functions | Microsoft Docs
スポンサーリンク