PowerShellでWindowsのイベントIDをリアルタイム監視し特定イベント発生時にアクションを実行する方法

PowerShellを使用してWindowsのイベントログをリアルタイムで監視し、特定のイベントIDが発生した際に自動でアクションを実行する方法について解説します。

Windowsのイベントログは、システムやアプリケーションの動作状況を記録する重要なログです。特に、システムエラーやセキュリティ関連のイベントは、素早く検出し適切な対応を行うことが求められます。PowerShellを利用すれば、これらのイベントをリアルタイムで監視し、特定のイベントIDが発生した際に自動でスクリプトを実行することが可能になります。

例えば、特定のエラーイベントが発生した場合にメールを送信したり、ログを別ファイルに保存したり、システムのリカバリー処理を実行することができます。本記事では、PowerShellの基本的なコマンドから実践的なスクリプトまでを詳しく解説し、イベント監視の自動化を実現する方法を紹介します。

目次
  1. Windowsのイベントログとは?
    1. イベントログの種類
    2. イベントIDとは?
  2. PowerShellでイベントログを取得する方法
    1. 1. Get-EventLog を使用する方法(旧式)
    2. 2. Get-WinEvent を使用する方法(推奨)
    3. Get-EventLog と Get-WinEvent の違い
  3. イベントIDのフィルタリング方法
    1. Get-EventLog でのフィルタリング(旧式)
    2. Get-WinEvent でのフィルタリング(推奨)
    3. Where-Object を使った高度なフィルタリング
    4. Get-WinEvent のフィルタリング方法まとめ
  4. PowerShellでイベントログをリアルタイム監視する方法
    1. Register-ObjectEvent を使用したリアルタイム監視
    2. Register-ObjectEvent の仕組み
    3. Get-WinEvent を使用したリアルタイム監視(WMIを使わない方法)
    4. Unregister-Event で監視を解除する
    5. まとめ
  5. 特定イベント発生時にアクションを実行する方法
    1. Register-WmiEvent を利用したアクションの実行
    2. Register-ObjectEvent を利用したアクションの実行
    3. Get-WinEvent を使用したアクションの実行(ループ監視)
    4. Task Scheduler(タスクスケジューラ)を使用したアクションの実行
    5. まとめ
  6. 実践例:イベントログ監視とメール通知の自動化
    1. 1. メール通知の設定
    2. 2. PowerShellスクリプトの作成
    3. 3. スクリプトの実行と監視
    4. 4. タスクスケジューラを利用した永続実行
    5. 5. スクリプトの動作確認
    6. 6. 監視を解除する
  7. まとめ
  8. PowerShellスクリプトの永続的な実行とタスクスケジューラの活用
    1. 1. Start-Job を使用したバックグラウンド実行
    2. 2. タスクスケジューラを使用した永続実行
    3. 3. サービスとして実行(高度な方法)
  9. まとめ
  10. トラブルシューティングと最適化のポイント
    1. 1. PowerShellスクリプトが正しく動作しない
    2. 2. イベントが監視できない
    3. 3. Register-WmiEvent でイベントが発生しない
    4. 4. メールが送信されない
    5. 5. タスクスケジューラでスクリプトが動作しない
  11. 6. 最適化のポイント
    1. ログの記録を追加
    2. エラー処理を追加
  12. まとめ
  13. まとめ

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-EventLogGet-WinEvent の違い

比較項目Get-EventLogGet-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 のフィルタリング方法まとめ

フィルタリング方法コマンド例
特定のイベントIDGet-WinEvent -FilterHashtable @{LogName='Security'; Id=4624}
複数のイベントIDGet-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-WinEventRegister-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スクリプトを実行するタスクを作成

  1. タスクスケジューラを開くtaskschd.msc を実行)
  2. 「基本タスクの作成」→ 「トリガー」 で「特定のイベント発生時」を選択
  3. ログの種類、イベントID(例:4625)を指定
  4. 「操作」で「プログラムの開始」→ powershell.exe を指定
  5. 「引数」に -File "C:\Scripts\action.ps1" を指定
  6. タスクを保存し、動作を確認

まとめ

  • 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のタスクスケジューラを使用して常時実行できるように設定します。

手順

  1. タスクスケジューラを開くtaskschd.msc を実行)
  2. 「基本タスクの作成」 をクリック
  3. 「トリガー」 で「ログオン時」または「システム起動時」を選択
  4. 「操作」 で「プログラムの開始」を選択
  5. 「プログラム/スクリプト」powershell.exe を入力
  6. 「引数の追加」-ExecutionPolicy Bypass -File "C:\Scripts\MonitorLoginFailures.ps1" を入力
  7. 「OK」を押してタスクを保存
  8. タスクを右クリック → 「有効にする」 を選択し、起動

5. スクリプトの動作確認

  1. タスクスケジューラを使用してスクリプトを起動
  2. 別のユーザーでログオン失敗を発生させる
  3. 管理者メールに通知が届くことを確認

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"
}

タスクスケジューラの設定

  1. タスクスケジューラを開くtaskschd.msc を実行)
  2. 「タスクの作成」 をクリック
  3. 「全般」タブ
  • 名前: EventMonitor
  • 「最上位の特権で実行する」にチェックを入れる(管理者権限)
  1. 「トリガー」タブ
  • 「新規」 をクリックし、「ログオン時」または「システム起動時」 を選択
  1. 「操作」タブ
  • 「新規」→ 「プログラムの開始」 を選択
  • 「プログラム/スクリプト」に powershell.exe を指定
  • 「引数の追加」に -ExecutionPolicy Bypass -File "C:\Scripts\EventMonitor.ps1" を入力
  1. 「OK」を押してタスクを保存
  2. タスクを右クリック → 「実行」して動作を確認

3. サービスとして実行(高度な方法)

Windowsのタスクスケジューラよりもより確実に実行したい場合、スクリプトをWindowsサービスとして登録することも可能です。これには nssm(Non-Sucking Service Manager)を使用します。

nssmをインストール

  1. nssm をダウンロード(https://nssm.cc/)
  2. 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-JobPowerShellセッションを閉じると停止
タスクスケジューラシステム起動時に自動実行可能、一般的な方法
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を使用する場合、アプリパスワードの設定が必要です。

ファイアウォール設定を確認
企業ネットワークでは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-WinEventGet-EventLog を使用したログの取得方法を紹介しました。次に、Register-WmiEvent を活用してリアルタイム監視を行い、特定のイベントが発生した際にメール通知やスクリプト実行を自動化する方法を解説しました。

さらに、監視スクリプトを永続実行する方法として、タスクスケジューラやWindowsサービス化(nssmの活用) についても説明しました。最後に、スクリプト実行時のトラブルシューティングや、エラーハンドリングの方法について詳しく解説しました。

適切なイベント監視と自動化により、システムの監視を効率化し、異常を迅速に検知・対応できるようになります。本記事のスクリプトを活用し、Windows環境の監視と自動化を進めてみてください。

コメント

コメントする

目次
  1. Windowsのイベントログとは?
    1. イベントログの種類
    2. イベントIDとは?
  2. PowerShellでイベントログを取得する方法
    1. 1. Get-EventLog を使用する方法(旧式)
    2. 2. Get-WinEvent を使用する方法(推奨)
    3. Get-EventLog と Get-WinEvent の違い
  3. イベントIDのフィルタリング方法
    1. Get-EventLog でのフィルタリング(旧式)
    2. Get-WinEvent でのフィルタリング(推奨)
    3. Where-Object を使った高度なフィルタリング
    4. Get-WinEvent のフィルタリング方法まとめ
  4. PowerShellでイベントログをリアルタイム監視する方法
    1. Register-ObjectEvent を使用したリアルタイム監視
    2. Register-ObjectEvent の仕組み
    3. Get-WinEvent を使用したリアルタイム監視(WMIを使わない方法)
    4. Unregister-Event で監視を解除する
    5. まとめ
  5. 特定イベント発生時にアクションを実行する方法
    1. Register-WmiEvent を利用したアクションの実行
    2. Register-ObjectEvent を利用したアクションの実行
    3. Get-WinEvent を使用したアクションの実行(ループ監視)
    4. Task Scheduler(タスクスケジューラ)を使用したアクションの実行
    5. まとめ
  6. 実践例:イベントログ監視とメール通知の自動化
    1. 1. メール通知の設定
    2. 2. PowerShellスクリプトの作成
    3. 3. スクリプトの実行と監視
    4. 4. タスクスケジューラを利用した永続実行
    5. 5. スクリプトの動作確認
    6. 6. 監視を解除する
  7. まとめ
  8. PowerShellスクリプトの永続的な実行とタスクスケジューラの活用
    1. 1. Start-Job を使用したバックグラウンド実行
    2. 2. タスクスケジューラを使用した永続実行
    3. 3. サービスとして実行(高度な方法)
  9. まとめ
  10. トラブルシューティングと最適化のポイント
    1. 1. PowerShellスクリプトが正しく動作しない
    2. 2. イベントが監視できない
    3. 3. Register-WmiEvent でイベントが発生しない
    4. 4. メールが送信されない
    5. 5. タスクスケジューラでスクリプトが動作しない
  11. 6. 最適化のポイント
    1. ログの記録を追加
    2. エラー処理を追加
  12. まとめ
  13. まとめ