How to Build a Logging Function in PowerShell

PowerShell でログ関数を作成する

監視とデバッグを行うには、スクリプトが何を実行しているのかを把握しておくことが重要です。

スクリプトの監視は、スクリプトがどう実行されるかによって方式が異なります。 スクリプトがインタラクティブに呼び出される場合、つまり、Write-VerboseWrite-InformationWrite-Host などを使用してコンソールから直接呼び出される場合は、各コマンドはスクリプトの実行中にコンソールにメッセージを表示できるので、そのときにチェックできます。しかし、スクリプトが、スケジュールされたタスクから、または実行中に画面を見る人間を必要としない他のプロセスによって呼び出されたケースではどうでしょうか?この場合、 別のレベルの監視を組み込む必要があります。対話的に実行されるのではないスクリプトを監視するには、ログファイルに書き込むようにするのが秀逸な手法です。

PowerShell でテキストをログファイルに書き込む方法はいくつかあり、どれを使用するかは完全にスクリプト作成者次第です。ただ、ログ機能を作成に着手する前に、留意すべきことがいくつかあります。

  • すべてのログファイルのラインは、構造化されたコンテンツでなければなりません。ばらばらのテキストメッセージを散在させないようにしてください。
  • 各ログエントリの時間を記録する必要があります。
  • ログファイルの情報を後からフィルタリングできるよう、重大度などの「タグ」付けをしておくことが大切です。

では、スクリプトに組み込む PowerShell 関数をどのようにして作成するかを見てみましょう。この関数は異なるスクリプトで使用できる必要があるので、関数を保存するためだけに PS1 スクリプトを作成します。関数の名前は Write-Log とします。

Write-Log.ps1

function Write-Log {
    [CmdletBinding()]
    param()

}

このログ関数は、呼び出されるたびにログファイルに1ラインを書き込みます。ログの各ラインには、記録する内容に応じて変化する2つの属性、メッセージと重大度、を書き込みます。それらを関数にパラメータとして追加します。

function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Message,

        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Information','Warning','Error')]
        [string]$Severity = 'Information'
    )

}

重大度(Severity)パラメータの値は、3つの選択肢に制限してあります。3つの選択肢からどれかを選択する方式なので、このフィールドは常に3つの異なる重大度のうちの1つが入ることになります。パラメータを作成したら、CSV を使用して構造化ログファイルを作成します。構造化されていれば、必要に応じてスプレッドシートプログラムでログファイルを引き出し、簡単にデータをチェックすることができます。また以下のように、時間も追加しました。これは、関数が実行された時刻であって、パラメータではありません。

function Write-Log {
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Message,

        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Information','Warning','Error')]
        [string]$Severity = 'Information'
    )

    [pscustomobject]@{
        Time = (Get-Date -f g)
        Message = $Message
        Severity = $Severity
    } | Export-Csv -Path "$env:Temp\LogFile.csv" -Append -NoTypeInformation
}

Write-Log 関数についてはこれですべてです。ドットソース形式で読み込むようにすれば、どのスクリプトでも使用できます。Write-Log.ps1 スクリプトが、呼び出し元のスクリプトと同じフォルダにある場合は、次のようにします。

Script.ps1

. "$PSScriptRoot\Write-Log.ps1

スクリプトが関数を認識すると、スクリプトで必要な回数だけ呼び出すことができます。

$foo = $false
if ($foo) {
    Write-Log -Message 'Foo was $true' -Severity Information
} else {
    Write-Log -Message 'Foo was $false' -Severity Error
}

情報は、次のような形で、ログファイルに書き込まれます。

PS> Import-Csv "$env:Temp\LogFile.csv"

Time              Message        Severity
----              -------        --------
5/13/2017 2:19 PM Foo was $false Error

Log Management が備わった WhatsUp Gold は、無料でお試しいただけます。

WhatsUp Gold をお試しください