記事公開日
【PowerShell 初心者向け】ログ作成関数を作ろう

皆さんこんにちは。
日々の業務でプログラムを動かす中で、「あれ、今何が起きているんだろう?」「どこでエラーが出たんだろう?」と頭を抱えることはありませんか? そんな時に役立つのが「ログ」です。
ログは、プログラムが実行中に「今、何をしているか」「どんな問題が発生したか」といった情報を記録する、いわばプログラムの「日記」のようなものです。
PowerShellにおいては、ログを抽出する場合Transcriptを利用できますが、欲しい情報のみ、あるいは欲しいタイミングでログ出力させるにはひと手間必要です。
そこで筆者が作成したログ作成関数を掲載いたします。ぜひご活用ください。
なぜログが重要なのか?
プログラムを動かす上で、ログは単なる記録以上の非常に重要な役割を担っています。
言い換えれば、プログラムにおける「活動日誌」や「対話記録」のようなものです。
- デバッグ: 予期せぬエラーが起きた時、ログには「どこで」「何が原因で」「どのような状況で」エラーが発生したかの詳細が記録されます。 ログがあれば問題解決(デバッグ)の時間を大幅に短縮し、効率的な対応が可能になります。
- 監視: ログはプログラムの現在の動作状況や進行状況を「見える化」する役割があります。 プログラムが滞りなく動いているか、特定の処理が完了したかなどをリアルタイムで監視し、異常を早期に発見できます。
- 監査: 誰が、いつ、何を操作したかといった情報を記録し、後から振り返ることができます。
ログ作成関数本体
紹介する関数はこちらです。詳細はのちほど解説します。
※なお、ログの取得は本来であれば取得するレベルを指定して出力するのが一般的かと思います。
この記事で伝えたいことはログ出力をまとめて行うことができる関数の作り方となりますので、レベル指定の話は行いません。
予めご了承ください。
function Write-Log {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]$message,
[ValidateSet("INFO", "WARNING", "ERROR", "DEBUG", "VERBOSE", "READ")]
[string]$level = "INFO",
[string]$logFilePath
)
process {
$timeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$inputRead = $null
$logEntry = "[{0}][{1,-7}]{2}" -f $timeStamp, $level, $message
switch ($level){
"INFO" { Write-Host $logEntry -ForegroundColor Green}
"WARNING" { Write-Host $logEntry -ForegroundColor DarkYellow}
"ERROR" { Write-Host $logEntry -ForegroundColor Red}
"DEBUG" { Write-Debug $logEntry}
"VERBOSE" { Write-Verbose $logEntry}
"READ" { $inputRead = Read-Host $logEntry}
default { Write-Host $logEntry}
}
# 指定のファイルへ書き込みを行う
if (-not [string]::IsNullOrEmpty($logFilePath)) {
try {
$logDirectoryPath = Split-Path -Path $logFilePath
if (-not (Test-Path -Path $logDirectoryPath)){
# なければ新規で作成
New-Item -ItemType Directory -Path $logDirectoryPath -Force | Out-Null
}
Add-Content -Path $logFilePath -Value $logEntry -Encoding UTF8 -ErrorAction Stop
}
catch {
Write-Warning "ログファイルへの書き込みに失敗しました: $($logFilePath)。エラー: $($_.Exception.Message)"
}
}
# READを選択していた場合、入力値を返す
if ($null -ne $inputRead){
return $inputRead
}
}
}
関数の主要な引数(パラメータ)
- $message:
必須の引数です。呼び出された際のメッセージがここに格納されます。
例えば、「処理を開始しました」や「データが見つかりません」といった具体的なメッセージです。 - $level:
メッセージの「重要度」や「種類」を示す引数です。 デフォルトでは "INFO" が設定されています。このレベルを指定することで、ログの表示方法が変わったり、フィルターをかけやすくなったりします。
ValidateSetで呼び出し時に指定ができます。 - $logFilePath:
ログを「どこに」ファイルとして出力するかを指定するパスです。
このパスが指定されていると、画面表示だけでなく、指定されたファイルにもログが追記されていきます。 もし指定されたディレクトリが存在しない場合でも、Write-Log 関数が自動的に作成してくれるので安心です。
関数内の変数について
- $timeStamp:
ログが出力された正確な日時を記録するために使用します。 「年-月-日 時:分:秒」形式の現在時刻の文字列を格納します。 - $inputRead:
Write-Log関数がユーザーからの入力を受け取る特殊なケースで、その入力値を保持するために使用します。 - $logEntry:
コンソールに表示するための整形されたログメッセージの文字列を生成するために使用します。
ログレベルは7文字の固定幅で左揃えとなります。
ログの$levelとは?
$level引数にはいくつかの選択肢があります。
levelを適切に使い分けることで、必要な情報だけを効率的に確認できます。
- "INFO":
一般的な情報メッセージです。
処理の開始や完了、正常な動作を示す際に使用され、コンソールでは緑色で表示されます。 - "WARNING":
警告メッセージです。
処理は継続できるが、注意が必要な事象を示す際に使用され、コンソールでは濃い黄色(DarkYellow)で表示されます。 - "ERROR":
エラーメッセージです。
プログラムの続行が困難な重大な問題を示す際に使用され、コンソールでは赤色で表示されます。 - "DEBUG":
デバッグ時にのみ表示したい詳細なメッセージです。開発中の動作確認などで使用されます。
コンソールではWrite-Debug コマンドレットを通じて出力されます。 - "VERBOSE":
通常は表示されないが、より詳細な情報が必要な場合に表示されるメッセージです。
コンソールではWrite-Verbose コマンドレットを通じて出力されます。 - "READ":
唯一、ユーザーからの入力を受け付けるための特殊なレベルです。
このレベルを指定すると、メッセージが表示された後、ユーザーが何かを入力するまでプログラムが一時停止し、入力された値が関数の戻り値として返されます。
使用例
使用例としてはこのようなログが表示されます。
特にERRORの場合はエラー制御用の関数を作っておくことで詳細なエラー内容を出すことができるでしょう。
"INFO"の場合...
Write-Log "プログラムが起動しました。"
# [2025-08-14 10:53:47][INFO ]プログラムが起動しました。
"ERROR"の場合...
Write-Log "予期せぬエラーが発生しました。" -level ERROR
# [2025-08-14 10:55:15][ERROR ]予期せぬエラーが発生しました。
"DEBUG"の場合...
Write-Log "変数の値を確認します: $env:COMPUTERNAME" -level "DEBUG"
# 表示なし…⇒ -Debugスイッチを付けないとDEBUGログは表示されない
Write-Log "デバッグ情報" -level "DEBUG" -Debug
# デバッグ: [2025-08-14 10:56:36][DEBUG ]デバッグ情報
最後に
今回は、PowerShellで実践的なログ出力関数を作成する方法について解説しました。
エラー処理やレベルごとの出力制御といった機能は、スクリプトの内部的な動作を把握し、問題を追跡する上で非常に役に立ちます。
ご紹介した関数は、そのままプロジェクトで利用することも可能ですが、これを元にしてご自身の要件に合わせて改良していくことも可能です。
例えば、出力形式をJSONに変更して他のシステムと連携しやすくしたり、特定のログファイルパスをデフォルトに設定したりと様々な応用が考えられます。
ログは、プログラムのデバッグや安定運用のために欠かせない要素です。
開発時だけでなく、将来のメンテナンスやトラブルシューティングの場面においても、適切に残されたログは問題解決の大きな助けとなることでしょう。
この記事でご紹介した関数が、皆さまのコードの品質をさらに高めるための一助となれば幸いです。