how-to-search-windows-event-logs-across-hundreds-of-servers

何百ものサーバーからの Windows イベントログを検索する方法

何百ものサーバーからの Windows イベントログを検索する方法

トラブルシューティングや潜在的なセキュリティ侵害の調査を開始するときは、取り掛かりとして、まず Windows のイベントログをチェックすることが多いと思います。

Windows は、プロバイダでグループ化された広範にわたる様々なイベントログのリストを記録し、ときには驚くべき数のイベントが記録されることもあります。どのような内容かにかかわらず、すべてのイベントが記録されているので、何が起こっているのかを正確に把握するのは困難です。何百ものサーバーからイベントログを検索するには、PowerShell を使用する方法があります。

 

PowerShell には、Get-EventLogGet-WinEvent という2つのイベントログをクエリできるコマンドがあります。このブログでは、すべての種類のイベントログをサポートし、より優れたフィルタリング機能を備えている Get-WinEvent に焦点を当てます。

サーバーにイベントをクエリするのは、Get-WinEvent を使って簡単に行うことができます。Get-WinEvent コマンドレットには、リモートサーバーを指定できる ComputerName というパラメータがあります。LogName パラメータを使用してクエリするイベントログの名前も指定する必要があります。下に示すように、プロバイダによってグループ化されたアウトプットが得られます。

PS> Get-WinEvent -ComputerName SRV1 -LogName System

   ProviderName: Microsoft-Windows-NDIS

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
3/14/2019 9:20:50 AM         10400 Warning          The network interface "Intel(R) PRO/1000 MT Network Connection" has begun resetting.  There will ...
3/14/2019 9:12:16 AM         10400 Warning          The network interface "Intel(R) PRO/1000 MT Network Connection" has begun resetting.  There will ...


   ProviderName: Service Control Manager

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
3/14/2019 8:08:46 AM          7040 Information      The start type of the Background Intelligent Transfer Service service was changed from auto start...
<SNIP>

通常は、ログのすべてのイベントをチェックすることは避けたいので、出力を制限するオプションがあります。その1つとして、MaxEvents パラメータを使用することができますが、これは結果をフィルタするわけではなく、返されるイベントの数を制限するだけです。

PS> Get-WinEvent -ComputerName SRV1 -LogName System -MaxEvents 1

出力を絞り込むために、Get-WinEvent でイベントをフィルタ処理する方法として、FilterHashTable パラメータを使用することが可能です。フィルタリングのさまざまな属性を指定する入力としてハッシュテーブルを指定できます。

たとえば、FilterHashTable パラメータの内部で Level キーを使用して、重要度でイベントをフィルタ処理できます。下のケースでは、SRV1 サーバーのクリティカル・イベントとエラー・イベントだけが出力されます。

Get-WinEvent -ComputerName SRV1 -FilterHashtable @{
    LogName = 'System'
    Level = 1,2 # 1 Critical, 2 Error, 3 Warning, 4 Information
}

もう1つのよく使われるイベントログ・クエリとして、アカウントロックアウトのイベントを検索するものがあります。アカウントロックアウトの場合、Security ログに ID 4740 のイベントが生成されることがわかっているので、イベントログの名前とIDを使って絞り込みます。そのほか、プロバイダの名前でフィルタリングすることも可能です。このように、イベントログをフィルタリングするには様々な方法があります。

Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4740
}

Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    ProviderName = 'Microsoft-Windows-GroupPolicy'
}

イベントをクエリしてそれらをフィルタ処理する方法の基本は以上の通りです。次に、複数のコンピュータに対してクエリを実行する方法について説明します。これを行うには、リモートコンピュータ名ごとに Get-WinEvent コマンドを実行する必要があります。すべてのサーバーにクエリするために foreach ループを作成します。

テキストファイルの形でサーバーのリストを持っていて、そのすべてのサーバーのイベントログを検索したいとしましょう。それには、テキストファイルを読み込んで各サーバー名を返す Get-Content を使用して、返ってきた名前を foreach で1つずつ Get-WinEventComputerName パラメータに渡します。下は、C:\servers.txt テキストファイルで定義されているすべてのサーバーの最初の5つのシステム・イベントログを返すようクエリする例です。

$servers = Get-Content -Path C:\servers.txt
foreach ($server in $servers) {
    Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashtable @{
        LogName = 'System'
    }
}

これで求めるイベントは返ってきますが、それぞれのイベントがどのサーバーからのものなのかはわかりません。Select-Object を使用して、知りたいものだけ、ここではイベントIDとサーバー名(MachineName)が出力されるように制限することができます。

$servers = Get-Content -Path C:\servers.txt
foreach ($server in $servers) {
    Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashtable @{
        LogName = 'System'
    } | Select-Object -Property ID, MachineName
}

   Id MachineName
   -- -----------
 7036 SRV1.techsnips.local
10016 SRV2.techsnips.local
 7036 SRV3.techsnips.local

1台のコンピュータ用に適切なフィルタを作成できたら、foreach ループを使用してそれを複数のサーバーに拡張するのは簡単です。出力は、Select-Object を使用して、チェックしたいものだけを選択して最終レポートを作成できます。


Comments
Comments are disabled in preview mode.
Thanks for subscribing! Loading animation