PowerShellでイベントログをCSV出力(改行で崩れない版)


- イベントログを収集してCSV形式で出力するPowershellのサンプルスクリプトです。
- PSVersion 5.1@Windows10 で動作確認してます。
- Application,Systemの全レベル(重大、警告、エラー、情報）のログを直近の7日分取得します。フィルタ条件は 変数 $FilterHashtable のハッシュテーブルで指定しているので、直観的に変更可能だと思います。
- csvだとカラム中のメッセージに改行コードがあるとフォーマットが崩れてしまうので[LF] [CRLF]のようなタグに置換しています。


####スクリプト
PowerShellの青い画面を開き、以下のコードをそのまま張り付けてください。
カレントフォルダの配下にcsv形式でイベントログが出力されます。

```powershell:GetEvent_v0.77.ps1

# ----------------------------------------
# 0.変数初期化
# ----------------------------------------

$ScriptTime = Get-Date
$hostname=[string](hostname)
$yyyyMMdd_HHmmss=$ScriptTime.ToString("yyyyMMdd_HHmmss")

# ----------------------------------------
# 1.フィルタ時の条件を指定する
# ----------------------------------------


$FilterHashtable = @{
    level =
        "1", # 重大   : Critical Error
        "2", # 警告   : Error
        "3", # エラー : Warning
        "4", # 情報   : Information
        "5"  # 情報   : Verbose
    logname =
        "Application",
        "System" 
    starttime =
        $ScriptTime.AddHours(-24*7).ToString("yyyy/MM/dd HH:mm:ss") # 7日前
    endtime   =
        $ScriptTime.AddHours(-24*0).ToString("yyyy/MM/dd HH:mm:ss") # 現時点
} 


# ----------------------------------------
# 2.イベントログを取得する
# ----------------------------------------

$WinEventsDetail =Get-WinEvent -ErrorAction SilentlyContinue  -FilterHashtable $FilterHashtable -ComputerName $hostname

# ----------------------------------------
# 3.必用な出力項目だけを残す
# ----------------------------------------

 $SelectProperties  = @()

 $SelectProperties += "Message"
#$SelectProperties += "ActivityId"
#$SelectProperties += "Bookmark"
#$SelectProperties += "ContainerLog"
 $SelectProperties += "Id"
#$SelectProperties += "Keywords"
#$SelectProperties += "KeywordsDisplayNames"
 $SelectProperties += "Level"
 $SelectProperties += "LevelDisplayName"
 $SelectProperties += "LogName"
 $SelectProperties += "MachineName"
#$SelectProperties += "MatchedQueryIds"
#$SelectProperties += "Opcode"
#$SelectProperties += "OpcodeDisplayName"
#$SelectProperties += "ProcessId"
#$SelectProperties += "Properties"
#$SelectProperties += "ProviderId"
 $SelectProperties += "ProviderName"
#$SelectProperties += "Qualifiers"
 $SelectProperties += "RecordId"
#$SelectProperties += "RelatedActivityId"
 $SelectProperties += "Task"
 $SelectProperties += "TaskDisplayName"
 $SelectProperties += "ThreadId"
 $SelectProperties += @{name="TimeCreated";expression={$_.timecreated.tostring("yyyy/MM/dd HH:mm:ss")}}
 $SelectProperties += "UserId"
 $SelectProperties += "Version"

$WinEvents = $WinEventsDetail|select $SelectProperties

# ----------------------------------------
# 4.ファイル出力
# ----------------------------------------

# 変数を初期化
$out_folder = "WinEventOutput_$yyyyMMdd_HHmmss"
$CsvFilePath = "$out_folder\$hostname.WinEvents.csv" 

# ファイル出力用のフォルダを作成
mkdir $out_folder 

# イベントログの抽出結果をcsv形式でファイル出力 (改行コードは "[CRLF]" "[LF]" に置換 )
$WinEvents | % {$_.Message = $_.Message -replace "`r`n","[CRLF]"}
$WinEvents | % {$_.Message = $_.Message -replace "`n","[LF]"}
$WinEvents | Export-Csv  -Encoding Unicode -LiteralPath $CsvFilePath 

echo "イベントログを以下のファイルに保存しました"
ls ".\$CsvFilePath"


# イベントログの抽出条件をjson形式でファイル出力
$FilterHashtableFilePath = "$out_folder\FilterHashtable.json"
$FilterHashtable | ConvertTo-Json  | Out-File -LiteralPath  $FilterHashtableFilePath -Encoding Unicode 
echo "イベントログ抽出の条件を以下のファイルに保存しました"
ls $FilterHashtableFilePath
Read-Host "Enter キーを押すまで停止します" 

```

上記を実行すると、カレントフォルダに「WinEventOutput_yyyyMMdd_HHmmss」みたいフォルダが勝手に作成されてその中にCSV形式で結果が出力されます。

CSVに出力する項目は「# 3.必用な出力項目だけを残す」で定義している配列
`$SelectProperties`
で指定してます。
出力項目を増やしたり減らしたければ`$SelectProperties`の定義部分でコメント解除 or 追加 してください。

なお、上記のコード実行後に、同じPowerShellの青いウィンドウで以下のコードを張り付けると、
CSVの出力内容を読み込んでビューワで確認できます。(GlidViewが使えるGUI環境の場合のみ)

```powershell:GetEvent_v0.77_追加コード.ps1

# ----------------------------------------
# 5.CSV出力した結果を画面でも確認
# ----------------------------------------
$CheckContent = (Get-Content   -Encoding Unicode -LiteralPath $CsvFilePath |ConvertFrom-csv )
$CheckContent | % {$_.Message = $_.Message -replace "\[CRLF\]","`r`n"}
$CheckContent | % {$_.Message = $_.Message -replace "\[LF\]","`n"}
$CheckContent | select TimeCreated,LevelDisplayName,logname,ProviderName,id,message |ogv -Title "$CsvFilePath"
Read-Host "Enter キーを押すまで停止します" 

```

ここでビューワに出力する項目は
` select TimeCreated,LevelDisplayName,logname,ProviderName,id,message`
とすることで、重要だと思われる以下の列のみに絞っています。

- イベントの生成日時
- 重要度（緊急、重大、エラー、情報）
- ログ名（Application,Systemなど)
- プロバイダ名（イベントビューワの「ソース」に相当）
- イベントID
- メッセージ文面