次の方法で共有


about_Functions

簡単な説明

PowerShell で関数を作成して使用する方法について説明します。

詳細な説明

関数は、割り当てる名前を持つ PowerShell ステートメントの一覧です。 関数を実行するときは、関数名を入力します。

PowerShell では、次の 2 種類の関数が定義されています。

  • 関数は、名前で呼び出すことができるコードのブロックです。 入力と戻り値の出力を受け取ることができます。 関数は、 function キーワードを使用して定義されます。
  • フィルターは、パイプラインからのデータを処理するように設計された関数の一種です。 フィルターは、 filter キーワードを使用して定義されます。

関数内のステートメントは、4 つの定義済みスクリプト ブロックのいずれかにグループ化できます。 これらのスクリプト ブロックには、キーワード beginprocessend、および cleanを使用して名前が付けられます。 これらのキーワードを使用しない場合、PowerShell はステートメントを適切なコード ブロックに配置します。

関数はコマンドレットのように動作することもできます。 C#プログラミングを使用せずに、コマンドレットと同じように動作する関数を作成できます。 詳細については、「 about_Functions_Advanced」を参照してください。

重要

スクリプト ファイルとスクリプト ベースのモジュール内では、関数を呼び出す前に定義する必要があります。

関数の構文

関数は、次の構文を使用して定義されます。

function [<scope:>]<name> {
  param([type]$Parameter1 [,[type]$Parameter2])
  dynamicparam {<statement list>}
  begin {<statement list>}
  process {<statement list>}
  end {<statement list>}
  clean {<statement list>}
}

関数には、次の項目が含まれています。

  • function キーワード
  • スコープ (省略可能)
  • 選択した名前
  • 動的パラメーターを含む任意の数の名前付きパラメーター (省略可能)
  • 中かっこで囲まれた 1 つ以上の PowerShell ステートメント {}

function定義でキーワード (beginprocessendclean) を使用しない場合、PowerShell はステートメントを end ブロックに配置します。

関数の dynamicparam キーワードと動的パラメーターの詳細については、 about_Functions_Advanced_Parametersを参照してください。

関数は次のような単純な場合があります。

function Get-PowerShellProcess { Get-Process pwsh }

関数が定義されたら、組み込みのコマンドレットと同様に使用できます。 たとえば、新しく定義された Get-PowerShellProcess 関数を呼び出すには、次のようにします。

Get-PowerShellProcess
 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
    110    78.72     172.39      10.62   10936   1 pwsh

関数は、コマンドレットと同じくらい複雑な場合もあります。

関数は、表示、変数への割り当て、または他の関数またはコマンドレットに渡すことができる値を返すことができます。 return キーワードを使用して出力を返すことができます。 return キーワードは、関数から返される他の出力には影響しません。 ただし、 return キーワードは、その行で関数を終了します。 詳細については、「 about_Return」を参照してください。

フィルター構文

filter関数の目的は、パイプライン内の各オブジェクトで実行される関数を簡単に定義する方法を提供することです。

フィルターの構文は次のとおりです。

filter [<scope:>]<name> {<statement list>}

filter関数の構文を簡略化するには、スクリプト ブロック キーワード (beginprocessendclean) を省略します。 PowerShell は、ステートメントを process ブロックに配置します。 フィルター関数では他のブロックを使用できますが、パイプライン内の各オブジェクトを処理する唯一の目的を持つ関数を定義する簡単な方法を提供することを目的としていました。

次のフィルターは、パイプラインからログ エントリを取得し、エントリ全体またはエントリのメッセージ部分のみを表示します。

filter Get-EventMessage ([switch]$MessageOnly) {
  if ($MessageOnly) { Out-Host -InputObject $_.Message }
  else { $_ }
}

次のように使用できます。

Get-WinEvent -LogName System -MaxEvents 100 | Get-EventMessage -MessageOnly

入力処理メソッド

このセクションで説明するメソッドは、入力処理方法と呼ばれます。 関数の場合、この 3 つのメソッドは、関数の beginprocess、および end ブロックを使用して指定されます。 PowerShell 7.3 では、 clean ブロック プロセス メソッドが追加されています。

関数でこれらのブロックを使用する必要はありません。 名前付きブロックを使用しない場合、PowerShell は関数の end ブロックにコードを配置します。 ただし、これらの名前付きブロックのいずれかを使用するか、 dynamicparam ブロックを定義する場合は、すべてのコードを名前付きブロックに配置する必要があります。

次の例は、1 回限りの前処理用の begin ブロック、パイプラインからの process ブロック データ、および 1 回限りの後処理用の end ブロックを含む関数の概要を示しています。

Function Test-ScriptCmdlet {
    [CmdletBinding(SupportsShouldProcess=$true)]
    param ($Parameter1)
    begin{}
    process{}
    end{}
}

begin

このブロックは、関数のオプションの 1 回限りの前処理を提供するために使用されます。 PowerShell ランタイムは、パイプライン内の関数のインスタンスごとに、このブロック内のコードを 1 回使用します。

process

このブロックは、関数のレコードごとの処理を提供するために使用されます。 他のブロックを定義せずに、 process ブロックを使用できます。 processブロック実行の数は、関数の使用方法と、関数が受け取る入力によって異なります。

自動変数 $_ または $PSItem には、 process ブロックで使用するパイプライン内の現在のオブジェクトが含まれています。 $input自動変数には、関数とスクリプト ブロックでのみ使用できる列挙子が含まれています。 詳細については、「about_Automatic_Variables」を参照してください。

  • パイプライン入力なしで関数が呼び出された場合、PowerShell は process ブロックを 1 回だけ実行します。
  • パイプライン内では、 process ブロックは、関数に到達する入力オブジェクトごとに 1 回実行されます。
  • 関数に到達するパイプライン入力が空の場合、 process ブロックは実行されません。
    • beginend、およびcleanブロックは引き続き実行されます。

重要

関数パラメーターがパイプライン入力を受け入れ、 process ブロックが定義されていない場合、レコードごとの処理は失敗します。 この場合、関数は入力に関係なく 1 回だけ実行されます。

end

このブロックを使用して、関数にオプションの 1 回限りの後処理を提供します。

clean

clean ブロックは PowerShell 7.3 で追加されました。

clean ブロックは、beginprocess、および end ブロックにまたがっているリソースをクリーンアップする場合に便利です。 これは、スクリプト関数またはスクリプト コマンドレットの他のすべての名前付きブロックをカバーする finally ブロックと意味的に似ています。 リソースのクリーンアップは、次のシナリオに適用されます。

  1. エラーを終了せずにパイプラインの実行が完了したとき
  2. パイプラインの実行がエラーの終了よって中断されたとき
  3. パイプラインが切り捨てられると、次のようになります。 Select-Object -First
  4. パイプラインが Ctrl + c またはStopProcessing()

クリーン ブロックは 、成功 ストリームに書き込まれた出力をすべて破棄します。

注意事項

clean ブロックの追加は、破壊的変更です。 clean はキーワードとして解析されるため、ユーザーは clean という名前のコマンドをスクリプト ブロックの最初のステートメントとして直接呼び出すことができなくなります。 ただし、問題になる可能性はありません。 引き続き、呼び出し演算子 (& clean) を使用してコマンドを呼び出すことができます。

単純な関数

関数を複雑にする必要はありません。 最も単純な関数の形式は次のとおりです。

function <function-name> { statements }

たとえば、次の関数は、 管理者として実行 オプションを使用して PowerShell を起動します。

function Start-PSAdmin { Start-Process PowerShell -Verb RunAs }

この関数を使用するには、次のように入力します。 Start-PSAdmin

関数にステートメントを追加するには、各ステートメントを個別の行に入力するか、セミコロン (;) を使用してステートメントを区切ります。

たとえば、次の関数は、開始日より後に変更された現在のユーザーのディレクトリ内のすべての .jpg ファイルを検索します。

function Get-NewPicture {
  $start = Get-Date -Month 1 -Day 1 -Year 2010
  $allPics = Get-ChildItem -Path $Env:USERPROFILE\*.jpg -Recurse
  $allPics | Where-Object {$_.LastWriteTime -gt $Start}
}

便利な小さな関数のツールボックスを作成できます。 この記事で後述するように、これらの関数を PowerShell プロファイル に追加about_Profiles

関数名

関数には任意の名前を割り当てることができます。 ただし、他のユーザーと共有する関数の場合は、標準の PowerShell 名前付け規則に従う必要があります。

  • 名前は動詞と名詞のペアで構成する必要があります。動詞は関数が実行するアクションを識別し、名詞はコマンドレットがアクションを実行する項目を識別します。
  • 名前は、すべての PowerShell コマンドに対して承認済みの動詞を使用する必要があります。 承認された動詞を使用すると、ユーザーの一貫性が作成されます。

標準的な PowerShell 動詞の詳細については、「 Approved Verbs」を参照してください。

パラメーターを持つ関数

名前付きパラメーター、位置指定パラメーター、スイッチ パラメーター、動的パラメーターなど、関数でパラメーターを使用できます。 関数の動的パラメーターの詳細については、 about_Functions_Advanced_Parametersを参照してください。

名前付きパラメーター

任意の数の名前付きパラメーターを定義できます。 この記事で後述するように、名前付きパラメーターの既定値を含めることができます。

次のサンプル構文に示すように、 param キーワードを使用して中かっこ内のパラメーターを定義できます。

function <name> {
  param ([type]$Parameter1 [,[type]$Parameter2])
  <statement list>
}

次のサンプル構文に示すように、 param キーワードを指定せずに中かっこの外側にパラメーターを定義することもできます。

function <name> [([type]$Parameter1[,[type]$Parameter2])] {
  <statement list>
}

たとえば、次の関数は、代替構文を使用して 2 つのパラメーターを定義します。

function Add-Numbers([int]$One, [int]$Two) {
    $One + $Two
}

最初の方法が推奨されますが、これら 2 つの方法に違いはありません。

関数を実行すると、パラメーターに指定した値が、パラメーター名を含む変数に割り当てられます。 その変数の値は、関数で使用できます。

次の例は、 Get-SmallFilesと呼ばれる関数です。 この関数には、 $Size パラメーターがあります。 この関数は、 $Size パラメーターの値より小さいすべてのファイルを表示し、ディレクトリを除外します。

function Get-SmallFiles {
  param ($Size)
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

この関数では、パラメーターに定義されている名前である $Size 変数を使用できます。

この関数を使用するには、次のコマンドを入力します。

Get-SmallFiles -Size 50

パラメーター名を指定せずに名前付きパラメーターの値を入力することもできます。 たとえば、次のコマンドは、 Size パラメーターに名前を付けるコマンドと同じ結果になります。

Get-SmallFiles 50

パラメーターの既定値を定義するには、次の Get-SmallFiles 例に示すように、パラメーター名の後に等号と値を入力します。

function Get-SmallFiles ($Size = 100) {
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

値を指定せずに Get-SmallFiles を入力すると、 $sizeに 100 が割り当てられます。 値を指定すると、関数はその値を使用します。

必要に応じて、パラメーターの説明に PSDefaultValue 属性を追加し、PSDefaultValueHelp プロパティを指定することで、パラメーターの既定値を説明する簡単なヘルプ文字列を指定できます。 関数の Get-SmallFiles パラメーターの既定値 (100) を説明するヘルプ文字列を指定するには、次の例に示すように、PSDefaultValue 属性を追加します。

function Get-SmallFiles {
  param (
      [PSDefaultValue(Help = '100')]
      $Size = 100
  )
  Get-ChildItem $HOME | Where-Object {
    $_.Length -lt $Size -and !$_.PSIsContainer
  }
}

PSDefaultValue 属性クラスの詳細については、「PSDefaultValue Attribute Membersを参照してください。

位置指定パラメーター

位置指定パラメーターは、パラメーター名のないパラメーターです。 PowerShell では、パラメーター値の順序を使用して、各パラメーター値を関数内のパラメーターに関連付けます。

位置指定パラメーターを使用する場合は、関数名の後に 1 つ以上の値を入力します。 位置指定パラメーター値は、 $args 配列変数に割り当てられます。 関数名の後の値は、 $args 配列の最初の位置 ( $args[0]) に割り当てられます。

次の Get-Extension 関数は、指定したファイル名に .txt ファイル名拡張子を追加します。

function Get-Extension {
  $name = $args[0] + ".txt"
  $name
}
Get-Extension myTextFile
myTextFile.txt

パラメーターの切り替え

スイッチは、値を必要としないパラメーターです。 代わりに、関数名の後に switch パラメーターの名前を入力します。

switch パラメーターを定義するには、次の例に示すように、パラメーター名の前に [switch] 型を指定します。

function Switch-Item {
  param ([switch]$On)
  if ($On) { "Switch on" }
  else { "Switch off" }
}

関数名の後に On switch パラメーターを入力すると、関数に Switch onが表示されます。 switch パラメーターを指定しないと、 Switch offが表示されます。

Switch-Item -On
Switch on
Switch-Item
Switch off

次の例に示すように、 Boolean 値をスイッチの実行時に割り当てることもできます。

Switch-Item -On:$true
Switch on
Switch-Item -On:$false
Switch off

スプラッティングを使用してパラメーター値を渡す

スプラッティングを使用して、コマンドのパラメーターを表すことができます。 この機能は、Windows PowerShell 3.0 で導入されています。

セッションでコマンドを呼び出す関数では、この手法を使用します。 コマンド パラメーターを宣言または列挙したり、コマンド パラメーターが変更されたときに関数を変更したりする必要はありません。

次のサンプル関数は、 Get-Command コマンドレットを呼び出します。 このコマンドは、@argsのパラメーターを表すためにGet-Commandを使用します。

function Get-MyCommand { Get-Command @args }

Get-Command関数を呼び出すときは、Get-MyCommandのすべてのパラメーターを使用できます。 パラメーターとパラメーター値は、 @argsを使用してコマンドに渡されます。

Get-MyCommand -Name Get-ChildItem
CommandType     Name                ModuleName
-----------     ----                ----------
Cmdlet          Get-ChildItem       Microsoft.PowerShell.Management

@args機能では、$args自動パラメーターを使用します。これは、宣言されていないコマンドレット パラメーターと残りの引数の値を表します。

詳細については、「 about_Splatting」を参照してください。

オブジェクトを関数にパイプ処理する

任意の関数がパイプラインから入力を受け取ることができます。 beginprocessend、およびcleanキーワードを使用して、関数がパイプラインからの入力を処理する方法を制御できます。 次のサンプル構文は、これらのキーワードを示しています。

processステートメント リストは、パイプライン内のオブジェクトごとに 1 回実行されます。 process ブロックの実行中、各パイプライン オブジェクトは、$_自動変数 (一度に 1 つのパイプライン オブジェクト) に割り当てられます。

次の関数では、 process キーワードを使用します。 この関数は、パイプラインの値を表示します。

function Get-Pipeline
{
  process {"The value is: $_"}
}

1, 2, 4 | Get-Pipeline
The value is: 1
The value is: 2
The value is: 4

パラメーターからパイプライン入力または入力を受け取ることができる関数が必要な場合は、 process ブロックで両方のケースを処理する必要があります。 次に例を示します。

function Get-SumOfNumbers {
    param (
        [int[]]$Numbers
    )

    begin { $retValue = 0 }

    process {
        if ($null -ne $Numbers) {
           foreach ($n in $Numbers) {
               $retValue += $n
           }
        } else {
           $retValue += $_
        }
    }

    end { $retValue }
}

PS> 1, 2, 3, 4 | Get-SumOfNumbers
10
PS> Get-SumOfNumbers 1, 2, 3, 4
10

パイプラインで関数を使用すると、関数にパイプされたオブジェクトが $input 自動変数に割り当てられます。 この関数は、パイプラインからオブジェクトが取得される前に、 begin スクリプト ブロックを使用してステートメントを実行します。 この関数は、パイプライン内にオブジェクトが存在しない場合に、 end スクリプト ブロックを使用してステートメントを実行します。

次の例は、beginおよび end スクリプト ブロックで使用される$input自動変数を示しています。

function Get-PipelineBeginEnd {
    begin   { "Begin: The input is $input" }
    end     { "End:   The input is $input" }
}

パイプライン入力で関数を実行すると、次の結果が表示されます。

1, 2, 4 | Get-PipelineBeginEnd
Begin: The input is
End:   The input is 1 2 4

begin ステートメントを実行すると、関数にはパイプラインからの入力がありません。 end ステートメントは、関数が値を持った後に実行されます。

関数に process キーワードがある場合、 $input 内の各オブジェクトは $input から削除され、 $_に割り当てられます。 次の例には、 process ステートメント の一覧があります。

function Get-PipelineInput
{
    process {"Processing:  $_ " }
    end     {"End:   The input is: $input" }
}

この例では、関数にパイプされた各オブジェクトが、 process ステートメント リストに送信されます。 processステートメントは、各オブジェクト (一度に 1 つのオブジェクト) で実行されます。 関数が $input キーワードに達すると、end自動変数は空になります。

1, 2, 4 | Get-PipelineInput
Processing:  1
Processing:  2
Processing:  4
End:   The input is:

詳細については、「 列挙子の使用」を参照してください。

PowerShell 7.3 では、 clean ブロックが追加されました。 clean ブロックは、beginprocess、および end ブロックで作成および使用されるリソースをクリーンアップする場合に便利です。 これは、スクリプト関数またはスクリプト コマンドレットの他のすべての名前付きブロックをカバーする finally ブロックと意味的に似ています。 リソースのクリーンアップは、次のシナリオに適用されます。

  1. エラーを終了せずに、パイプラインの実行が正常に終了するとき
  2. パイプラインの実行がエラーの終了よって中断されたとき
  3. パイプラインが切り捨てられると、次のようになります。 Select-Object -First
  4. パイプラインが Ctrl + C またはStopProcessing()

注意事項

clean ブロックの追加は、破壊的変更です。 clean はキーワードとして解析されるため、ユーザーは clean という名前のコマンドをスクリプト ブロックの最初のステートメントとして直接呼び出すことができなくなります。 ただし、問題になる可能性はありません。 このコマンドは、呼び出し演算子 (& clean) を使用して引き続き呼び出すことができます。

関数スコープ

関数は、作成するスコープ内に存在します。

関数がスクリプトの一部である場合、その関数はそのスクリプト内のステートメントで使用できます。 既定では、スクリプト内の関数は、そのスクリプトの外部では使用できません。

関数のスコープを指定できます。 たとえば、次の例では、関数がグローバル スコープに追加されます。

function Global:Get-DependentSvs {
  Get-Service | Where-Object {$_.DependentServices}
}

関数がグローバル スコープ内にある場合は、スクリプト、関数、およびコマンド ラインで関数を使用できます。

関数は新しいスコープを作成します。 変数などの関数で作成された項目は、関数スコープにのみ存在します。

詳細については、「 about_Scopes」を参照してください。

Function: ドライブを使用して関数を検索および管理する

PowerShell のすべての関数とフィルターは、 Function: ドライブに自動的に格納されます。 このドライブは、PowerShell Function プロバイダーによって公開されます。

Function: ドライブを参照する場合は、コンピューターのまたはC ドライブを参照する場合と同様に、D の後にコロンを入力します。

次のコマンドは、PowerShell の現在のセッションのすべての関数を表示します。

Get-ChildItem Function:

関数内のコマンドは、スクリプト ブロックとして関数の定義プロパティに格納されます。 たとえば、PowerShell に付属するヘルプ関数にコマンドを表示するには、次のように入力します。

(Get-ChildItem Function:help).Definition

次の構文を使用することもできます。

$Function:help

詳細については、「 about_Function_Provider」を参照してください。

新しいセッションで関数を再利用する

PowerShell コマンド プロンプトで関数を入力すると、関数は現在のセッションの一部になります。 この関数は、セッションが終了するまで使用できます。

すべての PowerShell セッションで関数を使用するには、PowerShell プロファイルに関数を追加します。 プロファイルの詳細については、「about_Profiles」を参照してください。

関数を PowerShell スクリプト ファイルに保存することもできます。 テキスト ファイルに関数を入力し、ファイル名拡張子を .ps1 してファイルを保存します。

関数のヘルプを作成する

Get-Help コマンドレットは、関数、コマンドレット、プロバイダー、スクリプトのヘルプを取得します。 関数のヘルプを取得するには、 Get-Help を入力し、その後に関数名を入力します。

たとえば、 Get-MyDisks 関数のヘルプを取得するには、次のように入力します。

Get-Help Get-MyDisks

次の 2 つの方法のいずれかを使用して、関数のヘルプを記述できます。

  • 関数のコメント ベースのヘルプ

    コメントに特別なキーワードを使用してヘルプを作成します。 関数のコメント ベースのヘルプを作成するには、コメントを関数の先頭、末尾、または本体内に配置する必要があります。 コメントベースのヘルプの詳細については、 about_Comment_Based_Helpを参照してください。

  • 関数の XML ベースのヘルプ

    ヘルプ コンテンツを複数の言語にローカライズする必要がある場合は、XML ベースのヘルプが必要です。 関数を XML ベースのヘルプ ファイルに関連付けるには、コメントベースのヘルプ キーワード .EXTERNALHELP 使用します。 このキーワードがないと、 Get-Help 関数ヘルプ ファイルが見つからず、自動生成されたヘルプのみが返されます。

    .EXTERNALHELP キーワードの詳細については、about_Comment_Based_Helpを参照してください。 XML ベースのヘルプの詳細については、「 コマンドレット ヘルプを記述する方法を参照してください。

関連項目