PowerShellを使用してWindowsのイベントログをリアルタイムで監視し、特定のイベントIDが発生した際に自動でアクションを実行する方法について解説します。
Windowsのイベントログは、システムやアプリケーションの動作状況を記録する重要なログです。特に、システムエラーやセキュリティ関連のイベントは、素早く検出し適切な対応を行うことが求められます。PowerShellを利用すれば、これらのイベントをリアルタイムで監視し、特定のイベントIDが発生した際に自動でスクリプトを実行することが可能になります。
例えば、特定のエラーイベントが発生した場合にメールを送信したり、ログを別ファイルに保存したり、システムのリカバリー処理を実行することができます。本記事では、PowerShellの基本的なコマンドから実践的なスクリプトまでを詳しく解説し、イベント監視の自動化を実現する方法を紹介します。
Windowsのイベントログとは?
Windowsのイベントログは、システム、アプリケーション、セキュリティ関連の動作を記録するログシステムです。Windows OSには標準で「イベントビューアー」というツールが備わっており、イベントログの詳細を確認できます。
イベントログの種類
Windowsのイベントログには、主に以下の種類があります。
- アプリケーションログ
ソフトウェア(アプリケーション)の動作状況やエラーを記録します。 - システムログ
Windows OSやドライバに関連するイベントを記録します。 - セキュリティログ
ユーザー認証やアクセス権の変更など、セキュリティに関するイベントを記録します。 - セットアップログ
Windowsのインストールや更新に関する情報を記録します。 - 転送イベントログ
他のコンピュータから転送されたイベントログを記録します。
イベントIDとは?
イベントログには、各イベントに固有のイベントIDが割り当てられています。これにより、特定のイベントを識別しやすくなります。例えば、次のようなイベントIDがあります。
- 4624:ユーザーのログオン成功
- 4625:ユーザーのログオン失敗
- 6006:システムのシャットダウン
- 1001:アプリケーションエラー
これらのイベントIDを活用することで、特定のログを抽出し、システムの監視やトラブルシューティングを効率化できます。次の章では、PowerShellを使ってイベントログを取得する方法を詳しく解説します。
PowerShellでイベントログを取得する方法
PowerShellを使用すると、Windowsのイベントログを簡単に取得できます。主に以下の2つのコマンドレットが利用されます。
1. Get-EventLog
を使用する方法(旧式)
Get-EventLog
は、Windowsの従来のイベントログ(System、Application、Security など)を取得するためのコマンドです。Windows 7 以前の環境でも利用可能ですが、最新のWindowsでは Get-WinEvent
の使用が推奨されています。
基本的な使い方
# システムログを取得
Get-EventLog -LogName System -Newest 10
このコマンドは、最新の10件のシステムイベントログを取得します。
特定のイベントIDを検索する
# イベントID 4624(ログオン成功)のログを取得
Get-EventLog -LogName Security -InstanceId 4624 -Newest 5
2. Get-WinEvent
を使用する方法(推奨)
Get-WinEvent
は、新しいWindowsイベントログ(EVTX形式)に対応しており、より強力で高速なフィルタリングが可能です。
基本的な使い方
# 最新の10件のシステムイベントログを取得
Get-WinEvent -LogName System -MaxEvents 10
特定のイベントIDをフィルタリング
# イベントID 4624(ログオン成功)のログを取得
Get-WinEvent -LogName Security | Where-Object { $_.Id -eq 4624 }
過去24時間のエラーログを取得
# 直近24時間のエラーログを取得
$startTime = (Get-Date).AddHours(-24)
Get-WinEvent -LogName Application -FilterHashtable @{LogName='Application'; Level=2; StartTime=$startTime}
Get-EventLog
と Get-WinEvent
の違い
比較項目 | Get-EventLog | Get-WinEvent |
---|---|---|
推奨環境 | 旧式(Windows 7以前) | 新しい環境(Windows 10以降推奨) |
フィルタリング性能 | 限定的 | 高速かつ詳細なフィルタリングが可能 |
イベントログ形式 | 旧イベントログ(EVT) | 新しいEVTX形式に対応 |
実行速度 | 遅い | 高速 |
Get-WinEvent
はフィルタリングの柔軟性が高く、大規模なログデータを効率よく処理できるため、特定のイベントIDをリアルタイムで監視する際に最適です。次の章では、イベントログのフィルタリング方法について詳しく解説します。
イベントIDのフィルタリング方法
PowerShellでは、イベントログを取得する際に特定のイベントIDのみを抽出することが可能です。フィルタリングを適用することで、必要な情報だけを効率よく取得できます。
Get-EventLog
でのフィルタリング(旧式)
Get-EventLog
を使用する場合、-InstanceId
パラメータを指定することで、特定のイベントIDを取得できます。
例:イベントID 4624(ログオン成功)の取得
Get-EventLog -LogName Security -InstanceId 4624 -Newest 10
このコマンドは、セキュリティログの中からイベントID 4624 のログを最新10件取得します。
例:複数のイベントIDを取得
Get-EventLog -LogName Security | Where-Object { $_.InstanceId -in @(4624, 4625) }
-in
演算子を使用することで、複数のイベントID を取得できます。
Get-WinEvent
でのフィルタリング(推奨)
Get-WinEvent
では、より強力なフィルタリングが可能です。特に、-FilterHashtable
を使うと、検索処理が高速化されます。
例:イベントID 4624 の取得
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 10
このコマンドは、セキュリティログの中からイベントID 4624 の最新10件を取得します。
例:複数のイベントIDを取得
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=@(4624, 4625)} -MaxEvents 10
Id=@(4624, 4625)
のように配列を渡すことで、複数のイベントIDを一括取得 できます。
例:過去24時間以内のエラーログ(Level=2)を取得
$startTime = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{LogName='Application'; Level=2; StartTime=$startTime}
Level=2
はエラーレベルのログを意味します。
Where-Object
を使った高度なフィルタリング
より詳細な条件でフィルタリングしたい場合は、Where-Object
を活用します。
例:イベントID 4624 のうち、特定のユーザーのログオンイベントのみ取得
Get-WinEvent -LogName Security | Where-Object { $_.Id -eq 4624 -and $_.Properties[5].Value -eq "Administrator" }
このスクリプトは、ログオン成功(ID: 4624)のイベントの中で、ユーザー名が Administrator
のものだけを抽出します。
Get-WinEvent
のフィルタリング方法まとめ
フィルタリング方法 | コマンド例 |
---|---|
特定のイベントID | Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} |
複数のイベントID | Get-WinEvent -FilterHashtable @{LogName='Security'; Id=@(4624, 4625)} |
特定時間内のログ | Get-WinEvent -FilterHashtable @{LogName='Application'; StartTime=(Get-Date).AddHours(-24)} |
Where-Object を使用 | Get-WinEvent -LogName Security | Where-Object { $_.Id -eq 4624 -and $_.Properties[5].Value -eq 'Administrator' } |
このように、PowerShellでは高度なフィルタリングを活用することで、特定のイベントIDのみをピンポイントで取得できます。次の章では、リアルタイム監視 の方法について詳しく解説します。
PowerShellでイベントログをリアルタイム監視する方法
Windowsのイベントログをリアルタイムで監視し、特定のイベントが発生した際に即座に対応できるようにするには、PowerShellのRegister-ObjectEvent
コマンドを活用します。
Register-ObjectEvent
を使用したリアルタイム監視
PowerShellでは、Get-WinEvent
をRegister-ObjectEvent
と組み合わせることで、特定のイベントが発生した際にリアルタイムで検知できます。
例:Windowsログオンイベント(ID 4624)のリアルタイム監視
$logName = "Security" # 監視対象のログ名
$eventID = 4624 # 監視するイベントID
# WMIイベントクエリを作成
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '$eventID' AND TargetInstance.Logfile = '$logName'"
# イベント監視を開始
Register-WmiEvent -Query $query -SourceIdentifier "LogonMonitor" -Action {
$event = $Event.SourceEventArgs.NewEvent.TargetInstance
Write-Output "ログオンイベント検出: $($event.Message)"
}
このスクリプトを実行すると、ログオン成功(イベントID 4624)が発生するたびにメッセージを出力します。
Register-ObjectEvent
の仕組み
PowerShellの Register-ObjectEvent
を使用すると、特定のオブジェクトの変化(イベント)を監視できます。
Register-ObjectEvent
の基本構文
Register-ObjectEvent -InputObject <監視対象オブジェクト> -EventName <イベント名> -SourceIdentifier <識別子> -Action { <実行するアクション> }
イベントが発生すると、指定した -Action
内のスクリプトが即時実行されます。
Get-WinEvent
を使用したリアルタイム監視(WMIを使わない方法)
WMIを使用せずに、Get-WinEvent
をループ処理で定期的にチェックする方法もあります。
例:Windowsログオンイベント(ID 4624)を1秒ごとにチェック
while ($true) {
$event = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 1 -ErrorAction SilentlyContinue
if ($event) {
Write-Output "ログオンイベント発生: $($event.TimeCreated) - $($event.Message)"
}
Start-Sleep -Seconds 1
}
このスクリプトは1秒ごとにログをチェックし、新しいログオンイベントを検出するとメッセージを出力します。
Unregister-Event
で監視を解除する
イベントの監視を停止したい場合は、Unregister-Event
コマンドを使用します。
Unregister-Event -SourceIdentifier "LogonMonitor"
また、Get-EventSubscriber
コマンドを使用すると、現在登録されているイベント監視を一覧表示できます。
Get-EventSubscriber
まとめ
Register-WmiEvent
を使うと、リアルタイムでイベントを監視できる。Get-WinEvent
のループ処理 でもイベント監視は可能。- 監視を解除するには
Unregister-Event
を使用する。
次の章では、特定のイベントが発生した際に、アクション(メール送信やファイル記録など)を自動で実行する方法を解説します。
特定イベント発生時にアクションを実行する方法
PowerShellでは、特定のイベントが発生した際に自動でアクションを実行できます。たとえば、ログオンイベントを検知してメールを送信したり、エラーログが記録された際に修復スクリプトを起動することが可能です。
Register-WmiEvent
を利用したアクションの実行
Register-WmiEvent
を使って、特定のイベントが発生したときに自動で処理を実行する方法を見ていきます。
例:ログオン成功(イベントID 4624)時に通知を表示
$logName = "Security"
$eventID = 4624
# WMIクエリを作成
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '$eventID' AND TargetInstance.Logfile = '$logName'"
# 監視を設定し、イベント発生時にポップアップメッセージを表示
Register-WmiEvent -Query $query -SourceIdentifier "LogonMonitor" -Action {
$event = $Event.SourceEventArgs.NewEvent.TargetInstance
[System.Windows.Forms.MessageBox]::Show("ログオン検出: $($event.Message)", "通知")
}
このスクリプトは、ユーザーがログオンするとポップアップ通知を表示します。
Register-ObjectEvent
を利用したアクションの実行
イベントが発生した際にスクリプトや外部プログラムを実行することも可能です。
例:特定のエラーログ(イベントID 1001)が発生したら、スクリプトを実行
$logName = "Application"
$eventID = 1001
$actionScript = "C:\Scripts\handleError.ps1" # 実行するスクリプトのパス
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '$eventID' AND TargetInstance.Logfile = '$logName'"
Register-WmiEvent -Query $query -SourceIdentifier "ErrorMonitor" -Action {
Write-Output "エラーイベント発生: $($Event.SourceEventArgs.NewEvent.TargetInstance.Message)"
Start-Process "powershell.exe" -ArgumentList "-ExecutionPolicy Bypass -File $actionScript"
}
このスクリプトは、イベントID 1001(アプリケーションエラー)が発生すると、指定したPowerShellスクリプト (handleError.ps1
) を自動実行します。
Get-WinEvent
を使用したアクションの実行(ループ監視)
Register-WmiEvent
の代わりに Get-WinEvent
を使い、定期的にイベントログをチェックしてアクションを実行する方法もあります。
例:特定のエラーログ(ID 1001)が発生したらメール送信
while ($true) {
$event = Get-WinEvent -FilterHashtable @{LogName='Application'; Id=1001} -MaxEvents 1 -ErrorAction SilentlyContinue
if ($event) {
# メール送信(Send-MailMessage コマンドを使用)
Send-MailMessage -To "admin@example.com" -From "monitor@example.com" -Subject "エラー通知" -Body "エラー発生: $($event.Message)" -SmtpServer "smtp.example.com"
Write-Output "エラーイベント発生: メールを送信しました"
}
Start-Sleep -Seconds 10 # 10秒ごとにチェック
}
このスクリプトは、イベントID 1001 が発生すると、メールを自動送信します。
Task Scheduler
(タスクスケジューラ)を使用したアクションの実行
PowerShellスクリプトをタスクスケジューラで実行することで、イベント発生時に確実に処理を実行できます。
例:特定のイベント発生時にPowerShellスクリプトを実行するタスクを作成
- タスクスケジューラを開く(
taskschd.msc
を実行) - 「基本タスクの作成」→ 「トリガー」 で「特定のイベント発生時」を選択
- ログの種類、イベントID(例:4625)を指定
- 「操作」で「プログラムの開始」→
powershell.exe
を指定 - 「引数」に
-File "C:\Scripts\action.ps1"
を指定 - タスクを保存し、動作を確認
まとめ
Register-WmiEvent
を使用すると、リアルタイムでイベントを監視し、自動でアクションを実行できる。Get-WinEvent
をループ処理で使う方法もあり、イベント発生時にメール送信やスクリプト実行が可能。- タスクスケジューラを利用すれば、PowerShellスクリプトを確実に実行できる。
次の章では、実際の応用例として「イベントログ監視とメール通知の自動化」を詳しく解説します。
実践例:イベントログ監視とメール通知の自動化
PowerShellを使ってWindowsのイベントログをリアルタイムで監視し、特定のイベントが発生した際にメールで通知を送信する方法を実践的に解説します。
1. メール通知の設定
PowerShellのSend-MailMessage
コマンドレットを使用すると、特定のイベントが発生した際にメールを自動送信できます。
SMTPサーバーの準備
PowerShellのSend-MailMessage
コマンドでメールを送信するには、SMTPサーバーが必要です。Gmailを使用する場合、以下の設定を行います。
設定項目 | 値 |
---|---|
SMTPサーバー | smtp.gmail.com |
ポート番号 | 587(TLS)または 465(SSL) |
認証方式 | ユーザー名・パスワード認証 |
Gmailを使用する場合、アプリパスワードを取得して設定する必要があります。
2. PowerShellスクリプトの作成
以下のスクリプトは、ログオン失敗(イベントID 4625)を監視し、検出時にメールを送信するものです。
# SMTP設定
$smtpServer = "smtp.gmail.com"
$smtpPort = 587
$from = "your-email@gmail.com"
$to = "admin@example.com"
$credential = Get-Credential # メール送信の認証情報を入力(アプリパスワード推奨)
# 監視対象のイベントログとイベントID
$logName = "Security"
$eventID = 4625 # ログオン失敗イベント
# WMIクエリの作成(リアルタイム監視)
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '$eventID' AND TargetInstance.Logfile = '$logName'"
# イベント監視とメール送信アクション
Register-WmiEvent -Query $query -SourceIdentifier "FailedLoginMonitor" -Action {
$event = $Event.SourceEventArgs.NewEvent.TargetInstance
$message = "ログオン失敗イベントが発生しました:`n`nイベントメッセージ:`n$($event.Message)"
# メール送信
Send-MailMessage -To $using:to -From $using:from -Subject "ログオン失敗検出" -Body $message -SmtpServer $using:smtpServer -Port $using:smtpPort -Credential $using:credential -UseSsl
}
3. スクリプトの実行と監視
このスクリプトを実行すると、ログオン失敗(ID: 4625)が発生すると即座にメールで通知が送信されます。
powershell -ExecutionPolicy Bypass -File "C:\Scripts\MonitorLoginFailures.ps1"
4. タスクスケジューラを利用した永続実行
このスクリプトをPowerShellで手動実行すると、スクリプトを閉じた瞬間に監視が終了してしまいます。そのため、Windowsのタスクスケジューラを使用して常時実行できるように設定します。
手順
- タスクスケジューラを開く(
taskschd.msc
を実行) - 「基本タスクの作成」 をクリック
- 「トリガー」 で「ログオン時」または「システム起動時」を選択
- 「操作」 で「プログラムの開始」を選択
- 「プログラム/スクリプト」 に
powershell.exe
を入力 - 「引数の追加」 に
-ExecutionPolicy Bypass -File "C:\Scripts\MonitorLoginFailures.ps1"
を入力 - 「OK」を押してタスクを保存
- タスクを右クリック → 「有効にする」 を選択し、起動
5. スクリプトの動作確認
- タスクスケジューラを使用してスクリプトを起動
- 別のユーザーでログオン失敗を発生させる
- 管理者メールに通知が届くことを確認
6. 監視を解除する
監視を停止するには、以下のコマンドを実行します。
Unregister-Event -SourceIdentifier "FailedLoginMonitor"
また、現在登録されているイベント監視を確認するには、以下を実行します。
Get-EventSubscriber
まとめ
- PowerShellを使って、特定のイベントID(例:ログオン失敗 4625)をリアルタイム監視できる。
Send-MailMessage
を使用し、イベント発生時にメール通知を送信できる。Register-WmiEvent
により、監視プロセスをバックグラウンドで実行可能。- タスクスケジューラを利用すれば、監視スクリプトを永続実行できる。
次の章では、スクリプトの永続実行とタスクスケジューラの活用方法をより詳しく解説します。
PowerShellスクリプトの永続的な実行とタスクスケジューラの活用
PowerShellで作成したイベント監視スクリプトは、そのまま実行するとセッション終了と同時に監視が停止してしまいます。そのため、スクリプトを常駐させる方法や、Windowsのタスクスケジューラを活用する方法を紹介します。
1. Start-Job
を使用したバックグラウンド実行
PowerShellのStart-Job
を使用すると、スクリプトをバックグラウンドで実行し続けることができます。
例:ログオン失敗イベントを監視するスクリプトをバックグラウンド実行
Start-Job -ScriptBlock {
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '4625' AND TargetInstance.Logfile = 'Security'"
Register-WmiEvent -Query $query -SourceIdentifier "FailedLoginMonitor" -Action {
$event = $Event.SourceEventArgs.NewEvent.TargetInstance
Write-Output "ログオン失敗イベント検出: $($event.Message)"
}
while ($true) { Start-Sleep -Seconds 10 } # 無限ループで維持
}
このスクリプトを実行すると、PowerShellのセッションを閉じてもバックグラウンドで実行され続けます。
バックグラウンドジョブの管理
バックグラウンドで実行されているジョブは以下のコマンドで確認できます。
Get-Job
ジョブを停止する場合は以下のコマンドを実行します。
Stop-Job -Id <ジョブID>
不要なジョブを完全に削除する場合は以下を実行します。
Remove-Job -Id <ジョブID>
2. タスクスケジューラを使用した永続実行
Windowsのタスクスケジューラを利用すれば、システム起動時にスクリプトを自動で実行し、監視を永続化できます。
PowerShellスクリプトの保存
まず、以下のスクリプトを C:\Scripts\EventMonitor.ps1
という名前で保存します。
$logName = "Security"
$eventID = 4625 # 監視するイベントID
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '$eventID' AND TargetInstance.Logfile = '$logName'"
Register-WmiEvent -Query $query -SourceIdentifier "FailedLoginMonitor" -Action {
$event = $Event.SourceEventArgs.NewEvent.TargetInstance
$message = "ログオン失敗イベントが発生しました:`n`nイベントメッセージ:`n$($event.Message)"
# ログに記録
Add-Content -Path "C:\Logs\FailedLogins.txt" -Value "$(Get-Date) - $message"
}
タスクスケジューラの設定
- タスクスケジューラを開く(
taskschd.msc
を実行) - 「タスクの作成」 をクリック
- 「全般」タブ
- 名前:
EventMonitor
- 「最上位の特権で実行する」にチェックを入れる(管理者権限)
- 「トリガー」タブ
- 「新規」 をクリックし、「ログオン時」または「システム起動時」 を選択
- 「操作」タブ
- 「新規」→ 「プログラムの開始」 を選択
- 「プログラム/スクリプト」に
powershell.exe
を指定 - 「引数の追加」に
-ExecutionPolicy Bypass -File "C:\Scripts\EventMonitor.ps1"
を入力
- 「OK」を押してタスクを保存
- タスクを右クリック → 「実行」して動作を確認
3. サービスとして実行(高度な方法)
Windowsのタスクスケジューラよりもより確実に実行したい場合、スクリプトをWindowsサービスとして登録することも可能です。これには nssm
(Non-Sucking Service Manager)を使用します。
nssmをインストール
nssm
をダウンロード(https://nssm.cc/)C:\nssm\nssm.exe
に保存
PowerShellスクリプトをサービスとして登録
コマンドプロンプトを管理者権限で開き、以下を実行します。
nssm install EventMonitor "powershell.exe" "-ExecutionPolicy Bypass -File C:\Scripts\EventMonitor.ps1"
これで EventMonitor
という名前のWindowsサービスが作成され、常にスクリプトが実行され続けるようになります。
サービスの管理
- サービスを開始:
net start EventMonitor
- サービスを停止:
net stop EventMonitor
- サービスを削除:
nssm remove EventMonitor confirm
まとめ
方法 | 特徴 |
---|---|
Start-Job | PowerShellセッションを閉じると停止 |
タスクスケジューラ | システム起動時に自動実行可能、一般的な方法 |
nssmを使ってサービス化 | より確実にスクリプトを永続実行できる |
Start-Job
は簡単にバックグラウンド実行が可能だが、セッション終了時に停止する- タスクスケジューラを活用すれば、PCの再起動後もスクリプトを自動で実行できる
nssm
を使うと、PowerShellスクリプトをWindowsサービスとして実行できる
次の章では、スクリプトのデバッグ方法やトラブルシューティングのポイントを解説します。
トラブルシューティングと最適化のポイント
PowerShellを使用してイベントログをリアルタイム監視し、特定のイベント発生時にアクションを実行する際、さまざまなエラーや問題が発生する可能性があります。本章では、よくあるトラブルの解決方法と、スクリプトの最適化ポイントを解説します。
1. PowerShellスクリプトが正しく動作しない
問題:PowerShellスクリプトを実行しても、イベントが検出されない・アクションが実行されない。
対処法
✅ スクリプトの実行ポリシーを確認
Get-ExecutionPolicy
実行ポリシーが Restricted
または AllSigned
になっている場合、スクリプトの実行が制限されているため、Unrestricted
または Bypass
に変更する。
Set-ExecutionPolicy Bypass -Scope Process -Force
✅ PowerShellを管理者として実行
一部のイベント(特に Security
ログ)は管理者権限が必要です。
→ PowerShellを「管理者として実行」する
✅ スクリプトの構文エラーを確認
スクリプトに誤字や構文エラーがないか -Verbose
オプションをつけてデバッグ。
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\EventMonitor.ps1" -Verbose
2. イベントが監視できない
問題:スクリプトを実行しても、特定のイベントが検知されない。
対処法
✅ イベントが発生しているか確認
Get-WinEvent -LogName Security -MaxEvents 5
→ 監視対象のイベントが発生しているか確認する。
✅ イベントIDを正しく指定しているかチェック
例えば、ログオン失敗(4625)ではなく、ログオン成功(4624)を監視しようとしていないか?
✅ WMIフィルタの構文ミスRegister-WmiEvent
を使う場合、WMIクエリの構文ミスがないか確認する。
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '4625' AND TargetInstance.Logfile = 'Security'"
3. Register-WmiEvent
でイベントが発生しない
問題:Register-WmiEvent
を実行しても、スクリプトがトリガーされない。
対処法
✅ 現在登録されているイベント監視を確認
Get-EventSubscriber
✅ 不要な監視を削除
Unregister-Event -SourceIdentifier "FailedLoginMonitor"
✅ タスクスケジューラやサービスとして登録している場合Register-WmiEvent
はバックグラウンドで実行されるため、タスクスケジューラを使用する際に セッションが閉じるとイベントが削除されてしまう ことがあります。
→ スクリプト内で無限ループを追加
while ($true) { Start-Sleep -Seconds 10 }
→ または nssm
を使ってWindowsサービスとして実行する(詳しくは a8 参照)。
4. メールが送信されない
問題:イベントが発生しても Send-MailMessage
が動作せず、メールが送信されない。
対処法
✅ SMTPサーバー設定を確認
Gmailの場合:
$smtpServer = "smtp.gmail.com"
$smtpPort = 587
または、Microsoft 365(Exchange):
$smtpServer = "smtp.office365.com"
$smtpPort = 587
✅ 認証エラーの対策
Gmailを使用する場合、アプリパスワードの設定が必要です。
- Googleアカウント → セキュリティ → アプリパスワードの生成
✅ ファイアウォール設定を確認
企業ネットワークではSMTPのポート(587/465)がブロックされていることがあります。
✅ テストメールを送信して確認
Send-MailMessage -To "admin@example.com" -From "your-email@gmail.com" -Subject "Test Mail" -Body "Test" -SmtpServer "smtp.gmail.com" -Port 587 -UseSsl
エラーが出る場合は -Credential
オプションでユーザー認証を設定。
5. タスクスケジューラでスクリプトが動作しない
問題:タスクスケジューラを設定したが、スクリプトが実行されない。
対処法
✅ タスクの履歴を確認
タスクスケジューラの「履歴」タブで、実行状況を確認。
✅ タスクを「最上位の特権」で実行
タスクスケジューラの 「最上位の特権で実行する」 にチェックを入れる。
✅ 引数の設定ミス
PowerShellをタスクスケジューラで実行する際、引数が正しく設定されているか確認。
プログラム/スクリプト: powershell.exe
引数の追加: -ExecutionPolicy Bypass -File "C:\Scripts\EventMonitor.ps1"
✅ タスクの「開始時刻」を手動設定
タスクのトリガーを 「システム起動時」または「ログオン時」 に設定。
✅ タスクを手動実行してテスト
Start-ScheduledTask -TaskName "EventMonitor"
6. 最適化のポイント
ログの記録を追加
リアルタイム監視スクリプトには、デバッグのためログファイルを記録する処理を入れる。
Add-Content -Path "C:\Logs\EventMonitor.log" -Value "$(Get-Date) - イベント検出"
エラー処理を追加
エラー発生時に処理を中断させないために、Try-Catch
を使用。
try {
# メール送信処理
Send-MailMessage -To "admin@example.com" -From "your-email@gmail.com" -Subject "通知" -Body "エラー発生" -SmtpServer "smtp.gmail.com" -Port 587 -UseSsl
} catch {
Add-Content -Path "C:\Logs\EventMonitor.log" -Value "$(Get-Date) - メール送信失敗: $_"
}
まとめ
- イベントが検知されない場合 →
Get-WinEvent
でログを確認、イベントIDやフィルタ設定をチェック Register-WmiEvent
の監視が動作しない →Get-EventSubscriber
で確認し、不要なイベントを解除- メールが送信されない → SMTPサーバー設定と認証情報を確認、テスト送信で動作をチェック
- タスクスケジューラが動作しない → 「最上位の特権で実行」、スクリプトの引数設定を見直し
- エラーが発生する場合 →
Try-Catch
を使ってエラーハンドリング、ログファイルを記録する
次の章では、本記事の内容をまとめます。
まとめ
本記事では、PowerShellを使用してWindowsのイベントログをリアルタイム監視し、特定のイベントが発生した際に自動でアクションを実行する方法を解説しました。
まず、Windowsイベントログの基本と、Get-WinEvent
や Get-EventLog
を使用したログの取得方法を紹介しました。次に、Register-WmiEvent
を活用してリアルタイム監視を行い、特定のイベントが発生した際にメール通知やスクリプト実行を自動化する方法を解説しました。
さらに、監視スクリプトを永続実行する方法として、タスクスケジューラやWindowsサービス化(nssmの活用) についても説明しました。最後に、スクリプト実行時のトラブルシューティングや、エラーハンドリングの方法について詳しく解説しました。
適切なイベント監視と自動化により、システムの監視を効率化し、異常を迅速に検知・対応できるようになります。本記事のスクリプトを活用し、Windows環境の監視と自動化を進めてみてください。
コメント