PowerShell スクリプトにおける関数
Aug 25, 2025
PowerShell の関数は、再利用可能なコードをモジュール化された保守しやすい単位にまとめ、スクリプト作成を簡単にし、エラーを減らします。 function キーワードで定義されており、パラメーターを含めたり、パイプライン入力を受け取ったり、 [CmdletBinding()] を使って cmdlet のように振る舞うことができます。関数は、Try/Catch によるエラー処理、詳細出力やデバッグ出力、モジュールの整理といった高度な機能をサポートします。ベストプラクティスには、意味のある命名、モジュール設計、オブジェクトの返却、コメントベースのヘルプによるドキュメント化が含まれます。
PowerShell の関数は、特定のタスクを実行するために設計されたコードのブロックです。関数を作成してテストしたら、複数のスクリプトで使い回せるため、コーディング作業の負担が減り、エラーのリスクも低減できます。適切に名付けられた関数を使うことで、スクリプトの読みやすさや保守性も向上します。さらに、関数は他の関数やコードブロックの入力として利用できる値を返せるため、複雑な処理を組み立てやすくなります。
この記事では、PowerShell 関数の使用を始めるために必要なすべてを説明します。重要なベストプラクティスも含め、さらに高度なオプションを深掘りするためのガイダンスも提供します。
PowerShell 関数の始め方
PowerShell で関数を作成する方法
関数を定義するには、function キーワードを使用します。基本的な構文は次のとおりです:
function <Function-Name> {
<Code-Block>
}
中かっこ {} の中にあるコードは、関数が呼び出されたときに実行されます。
必要に応じて、param キーワードを使用して、関数の引数(パラメータ)を、データ型、デフォルト値などとともに指定できます。パラメータを追加した構文は次のとおりです:
function <Function-Name> {
[param(
[<ParameterType>]$<ParameterName>,
[<ParameterType>]$<ParameterName2> = <DefaultValue>
)]
<Code-Block>
}
この PowerShell 関数の例では、2 つの数値を掛け合わせて結果を表示します:
function Multiply-Numbers {
param (
[int]$Number1,
[int]$Number2
)
$Result = $Number1 * $Number2
Write-Output "The multiplication value of $Number1 and $Number2 is $Result."
}
関数を保存する
関数を保存するには、.ps1 の拡張子が付いたスクリプト ファイルに保存するだけです。
関数を呼び出す
PowerShell で関数を呼び出すには、関数名のあとに必要な名前付きパラメーターを入力します。たとえば、上で定義した関数を呼び出す方法は次のとおりです:
Multiply-Numbers -number1 6 -Number2 8
現在のセッションの一部として関数を実行する(Dot-Sourcing)
Dot-sourcing を使うと、現在のコンソール セッション内で直接定義されているかのように PowerShell スクリプトを実行できます。Dot-sourcing を使用するには、関数を呼び出すときに関数名の前へ「. 」(ドットとスペース)を付けます。
たとえば、次の関数(Add-Numbers:
function Add-Numbers {
param (
[int]$Number1,
[int]$Number2
)
$Sum = $Number1 + $Number2
Write-Output "The sum of $Number1 and $Number2 is $Sum."
}
次のように、この関数をセッションに対して Dot-sourcing できます。
PowerShell 関数に名前を付ける
PowerShell 関数から最大限の価値を得るために、関数に名前を付ける際は次のガイドラインに従ってください。
動詞-名詞の形式を使います。
PowerShell には、名前が特定の形式に従うあらかじめ用意された一連の cmdlet が用意されています。形式は、「実行する操作」を表す動詞に続いて、「操作対象となるオブジェクト」を表す名詞が来ます。たとえば、get-user の cmdlet はユーザーに関する情報を取得し、remove-item は指定した項目を削除します。
作成する関数には同じ命名規則を守るのがベストプラクティスです。そうすることで、関数をより効果的に設計でき、再利用もしやすくなります。
承認済みの動詞を使用してください。
PowerShell では、関数で使用することが推奨される動詞の一覧が提供されています。一覧を表示するには、次の cmdlet を実行するだけです:
Get-Verb
わかりやすい名詞を選んでください。
関数に、組み込み cmdlet と同じ名前を付けないことが重要です。この問題を防ぐには、user や data. のような汎用的な名詞の使用を避けるのがよい方法です。代わりに、その関数が操作するデータの種類を明確に示す名詞を選んでください。たとえば、これらの関数の違いは次のように理解しやすいです: Get-EmployeeData, Get-UserInfo および Get-ServiceInfo。
バージョン管理の目的で関数名を使わないでください。
関数名にバージョン番号を付加すること(例:Get-UserInfoV2 )は推奨されません。スクリプトの理解が難しくなり、関数の古いバージョンを使ってしまう可能性も高まります。代わりに、ファイルのバージョン管理システムを通じてバージョン管理を行ってください。
高度な関数機能
パイプライン入力を受け取る
関数を設計して、パイプラインを介して別の関数やコマンドから入力を受け取るようにするには、ValueFromPipeline 属性を使用します。
例として、文字列のリストを1つずつ処理し、それぞれを大文字に変換して結果を出力する関数を作成してみましょう。分かりやすくするために、文字列の処理を3つの異なるブロックに分けます:
- BEGIN — このコードは、パイプラインの入力を処理する前に1回だけ実行されます。
- PROCESS — このセクションは、パイプラインに渡される各アイテムごとに実行され、入力オブジェクトを1つずつ処理します。
- END — すべての入力が処理された後に実行され、出力を最終的に確定します。
function Convert-ToUppercase {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline = $true, Mandatory = $true)]
[string]$InputString
)
BEGIN {
Write-Verbose "Starting the uppercase conversion process."
}
PROCESS {
if (-not [string]::IsNullOrWhiteSpace($InputString)) {
Write-Verbose "Processing string: $InputString"
$InputString.ToUpper()
} else {
Write-Verbose "Skipped empty or null string."
}
}
END {
Write-Verbose "Finished processing all strings."
}
}
パイプライン経由で提供された文字列のリストを変換するために、関数を呼び出す方法は次のとおりです。:
"hello", "world", "this", "is", "powershell" | Convert-ToUppercase -Verbose
軽量な関数である filters は、パイプライン経由で渡されたオブジェクトを処理するうえで非常に効率的な方法を提供できます。
関数を Cmdlet のように動作させる
基本関数を高機能な関数に変えるには、CmdletBinding 属性を使用します。これにより、定義済みの PowerShell パラメーターをサポートするなど、関数が cmdlet のように動作するようになります。
以下は、2つの数を足すために先ほど定義した基本関数です:
function Add-Numbers {
param (
[int]$Number1,
[int]$Number2
)
$Sum = $Number1 + $Number2
Write-Output "The sum of $Number1 and $Number2 is $Sum."
}
次のようにして、それを高度な関数にできます:
function Add-Numbers {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[int]$Number1,
[Parameter(Mandatory)]
[int]$Number2
)
process {
# Verbose Output
Write-Verbose "Starting addition of $Number1 and $Number2"
# Debugging Output
Write-Debug "Debugging: Ensuring numbers are valid integers"
# Perform the Addition
try {
$Result = $Number1 + $Number2
Write-Output $Result
} catch {
# Handle errors with error stream
Write-Error "An error occurred while performing the addition."
}
# Verbose Completion Message
Write-Verbose "Addition completed successfully"
}
}
Netwrix Auditor の無料トライアルを申し込む
関数モジュールの作成
関数モジュールとは、.psm1 という拡張子を持ち、関連する関数の集合が含まれるファイルです。関数をモジュールに整理することで、再利用性と保守性が向上します。
関数モジュールを作成するには、単にテキストファイルを作成して関数を貼り付け、.psm1 の拡張子で、C:\Program Files\WindowsPowerShell\Modules ディレクトリに保存します。たとえば、前に定義したAdd-Numbers 関数のような算術関数を含むモジュールを作成できるでしょう。
PowerShell セッションにモジュールを読み込むには、ここに示すImport-Module コマンドを使用します:
エラーハンドリング
PowerShell には、ゼロで割ろうとするなどのように、エラーによって関数の実行が停止してしまう可能性がある問題を、スムーズに処理するための複数のエラー処理手法があります。
Try/Catch/Finally ブロック
ある条件によって問題が発生し得ると分かっている場合、その条件を適切に処理するために、関数内で Try、Catch、Finally ブロックを使用できます。
- Try — このブロックには、エラーが発生し得るコード(たとえば除算など)が含まれます。エラーが発生しなければ、Catch ブロックは実行されません。
- Catch — Try ブロックでエラーが発生した場合、Catch ブロックがエラーの詳細を取得して処理することで、それを処理します。
- 最後に — このブロックは任意です。存在する場合、エラーが発生したかどうかに関係なく Try と Catch ブロックの後に実行されます。
-ErrorAction パラメーター
-ErrorAction パラメーターを使用すると、特定の関数でエラーをどのように処理するかを指定できます。指定できる値は次のとおりです:
- 続行 — エラーメッセージを表示して続行します。
- 停止 — エラーが発生した時点でスクリプトの実行を停止します。
- SilentlyContinue — エラーメッセージを非表示にして処理を続行します。
- Inquire — ユーザーに対して、エラーの扱い方を次のような選択肢で確認します: Yes, No および Retry。
- Ignore — メッセージすら表示せずに、エラーを完全に無視します。
以下に -ErrorAction パラメーターの例をいくつか示します。
Remove-Item "C:\path\to\nonexistentfile.txt" -ErrorAction SilentlyContinue
Get-Process -Name "Notepad" -ErrorAction Stop
$ErrorActionPreference 変数
変数 $ErrorActionPreference は、セッション内のすべての cmdlet に対して、エラーがグローバルにどのように処理されるかを制御します。この変数は、-ErrorAction パラメーターで上書きされない限り、すべてのコマンドにわたるエラー処理の動作に影響するよう設定できます。
詳細な例
以下は、複数のエラー処理方法を使用する例です。:
- $ErrorActionPreference 変数は、グローバルなエラー処理の優先設定を stop に設定するため、他の方法で処理されていないエラーが発生すると、実行が停止します。
- Try/Catch ブロックは、実行を停止せずにゼロで割ることによって発生し得るエラーを適切に処理します。Try ブロックが数学的な処理を行います。ゼロで割ることに遭遇すると、処理は Catch ブロックに移動し、エラーメッセージを表示します。
- この Finally ブロックは、エラーが発生したかどうかに関係なく実行され、操作が完了したことを示すメッセージが出力されます。
# Set global error action preference to 'Stop' to immediately halt on errors
$ErrorActionPreference = 'Stop'
function Perform-MathOperations {
param (
[int]$Num1,
[int]$Num2
)
try {
# Performing addition
Write-Host "Performing addition: $Num1 + $Num2"
$additionResult = $Num1 + $Num2
Write-Host "Addition Result: $additionResult"
# Checking for division by zero before performing division
if ($Num2 -eq 0) {
throw "Division by zero is not allowed."
}
# Performing division
Write-Host "Performing division: $Num1 / $Num2"
$divisionResult = $Num1 / $Num2
Write-Host "Division Result: $divisionResult"
}
catch {
# Catching any error that occurs in the try block
Write-Host "An error occurred: $_"
Write-Host "Error Type: $($_.Exception.GetType().Name)"
}
finally {
# This block always runs regardless of error occurrence
Write-Host "Finished performing math operations."
}
}
下のスクリーンショットは、この関数を2通りの方法で呼び出した結果を示しています。まず、有効な入力で呼び出します。
Perform-MathOperations -Num1 10 -Num2 2
次に、0で割ろうとする結果になる入力で呼び出します。
Perform-MathOperations -Num1 10 -Num2 0
関数のトラブルシューティング
関数の実行中にさまざまなレベルの詳細情報を提供するメッセージは Write-output (または Write-host)、 Write-Verbose および Write-Debug を使用して表示できます。この情報により、実行パスを手順ごとに追跡して、予期しない動作を特定するのに役立ちます。
たとえば、次のスクリーンショットでは、基本の Add-Numbers 関数を修正して、トラブルシューティングの詳細情報を提供する方法を示します。なお、デフォルトでは冗長メッセージのストリームは表示されないため、関数を呼び出す際に -Verbose を使用する必要があります。
Add-Numbers -Number1 5 -Number2 10 -Verbose
同様に、Write-Debug メッセージはデフォルトではコンソールに表示されませんが、関数を実行するときに -Debug を含めれば表示できます:
Add-Numbers -Number1 5 -Number2 10 -Debug
ベストプラクティス
- 各関数は1つのタスクだけを実行するように設計してください。そうすることで、テスト、利用、保守が容易になります。
- モジュール化された形で関数を設計し、さまざまなスクリプトで再利用できるようにします。
- パラメーターを使用するときは、それらの既定値を指定します。
- 関数には詳細なコメントを含めてください。コメントに基づくヘルプにより、デバッグと関数の再利用がしやすくなります。
- 再利用性を高めるために、関数がフォーマット済みの出力ではなくオブジェクトを返すようにしてください。
追加の例
次の関数は、エラー処理など、前に説明した多くの機能を示しています。:
# Function: Backup-Files
# Description: Backs up files from a source directory to a backup directory.
function Backup-Files {
param (
[Parameter(Mandatory = $true)]
[string]$SourcePath, # The directory containing the files to back up
[Parameter(Mandatory = $true)]
[string]$BackupPath, # The directory where files will be backed up
[string[]]$Extensions = @("*") # File extensions to back up (default: all files)
)
# Check if the source path exists
if (-not (Test-Path -Path $SourcePath)) {
Write-Error "Source path '$SourcePath' does not exist."
return
}
# Create the backup directory if it does not exist
if (-not (Test-Path -Path $BackupPath)) {
Write-Output "Creating backup directory at '$BackupPath'..."
New-Item -ItemType Directory -Path $BackupPath | Out-Null
}
# Get files matching the specified extensions
foreach ($extension in $Extensions) {
$files = Get-ChildItem -Path $SourcePath -Filter "*.$extension" -File -ErrorAction SilentlyContinue
foreach ($file in $files) {
$destination = Join-Path -Path $BackupPath -ChildPath $file.Name
Write-Output "Backing up file: $($file.FullName) -> $destination"
Copy-Item -Path $file.FullName -Destination $destination -Force
}
}
Write-Output "Backup completed successfully."
}
この関数を呼び出してすべてのファイルをバックアップしたり、ここで示すように特定のファイル拡張子だけを選択してバックアップしたりできます。:
Backup-Files -SourcePath "D:\Office\project" -BackupPath "D:\Backup" -Extensions @("csv", "txt")
まとめ
PowerShell の関数は、スクリプト作成に対して構造化されたアプローチを提供し、モジュール性、再利用性、保守性を向上させます。この記事に用意されているサンプルコードは、ぜひすべて試してみてください。自分自身の関数を作り始める際は、命名と使用に関するベストプラクティスを取り入れるようにしてください。
初心者向け Windows PowerShell スクリプト入門
eBook をダウンロード共有する
もっと詳しく
著者について
Tyler Reese
プロダクト マネジメント担当副社長、CISSP
ソフトウェア セキュリティ業界で20年以上の経験を持つ Tyler Reese は、今日の企業が直面している急速に変化するアイデンティティおよびセキュリティ上の課題について深く理解しています。現在、彼は Netwrix Identity and Access Management ポートフォリオのプロダクト ディレクターを務めており、市場動向の評価、IAM 製品ラインの方向性の設定、そして最終的にはエンド ユーザーのニーズに応えることが主な責任です。彼の専門的な経験は、Fortune 500 企業向けの IAM コンサルティングから、大手のダイレクト・トゥ・コンシューマー企業のエンタープライズ アーキテクトとしての業務まで多岐にわたります。現在、彼は CISSP の認定資格を保有しています。