Мониторинг журналов нескольких компьютеров с уведомлением по электронной почте — фильтр по идентификатору события

#email #powershell #notifications #event-log

#Адрес электронной почты #powershell #уведомления #журнал событий

Вопрос:

Ниже приведен код PowerShell, который собирает журналы событий из списка компьютеров, а затем отправляет электронное письмо получателям.

Что мне нужно, так это поиск определенного набора идентификаторов событий, а не поиск всех событий. Затем, если он увидит какое-либо указанное мной событие, он отправит отчет пользователю, иначе он просто завершится и не отправит никакого электронного письма.

 # Continue even if there are errors 
$ErrorActionPreference = "Continue";

# EMAIL PROPERTIES 
 # Set the recipients of the report. 
  $rcpts = "user@domain.com" 

# REPORT PROPERTIES 
 # Path to the report 
  $reportPath = "SomePath"; 

 # Report name 
  $reportName = "SomeFileName"; 

# Path and Report name together 
$logReport = $reportPath   $reportName 

# Get computer list to check logs 
$computers = 'servers.txt'

# Date coverage of logs to be monitored
$StartDate = (get-date).AddDays(-1)

# LogNames to be monitored
$logname = "System"

# Cleanup old files.. 
$Daysback = "-7" 
$CurrentDate = Get-Date; 
$DateToDelete = $CurrentDate.AddDays($Daysback); 
Get-ChildItem $reportPath | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item; 

# CSS style
$css= "<style>"
$css= $css  "BODY{ text-align: center; background-color:white;}"
$css= $css  "TABLE{    font-family: 'Lucida Sans Unicode', 'Lucida Grande', Sans-Serif;font-size: 12px;margin: 10px;width: 100%;text-align: center;border-collapse: collapse;border-top: 7px solid #004466;border-bottom: 7px solid #004466;}"
$css= $css  "TH{font-size: 13px;font-weight: normal;padding: 1px;background: #cceeff;border-right: 1px solid #004466;border-left: 1px solid #004466;color: #004466;}"
$css= $css  "TD{padding: 1px;background: ##FFFFFF;border-right: 1px solid #004466;border-left: 1px solid #004466;color: #669;hover:black;}"
$css= $css   "TD:hover{ background-color:#e5f7ff;}"
$css= $css  "</style>" 

# Process logs 
$body = Get-Content $computers | ForEach-Object {
    Get-WinEvent -ComputerName $_ -FilterHashtable @{logname=$logname; Level=1,2,3; starttime=$StartDate}    
}

if ($body)
{
    # Convert to HTML style 
    $body | ConvertTo-HTML -Head $css MachineName,LogName,LevelDisplayName,ID,TimeCreated,Message > $logReport

    # Get-Date for Email Subject
    $subjectDate = get-date -format F

    # EMAIL Properties
    $smtpServer = "smtp.domain.com" 
      $smtp = New-Object Net.Mail.SmtpClient($smtpServer) 
      $msg = New-Object Net.Mail.MailMessage 
      $msg.To.Add($rcpts) 
            $msg.From = "user@domain.com" 
      $msg.Subject = "EventLog Report for $subjectDate" 
            $msg.IsBodyHTML = $true 
            $msg.Body = get-content $logReport 
      $smtp.Send($msg) 
            $body = "Hello"
}
  

Ответ №1:

Вы можете попробовать ввести параметр ID в хэш-таблицу фильтра, а затем использовать If-Else инструкцию для включения и выключения поиска по идентификатору. Создайте свой текстовый файл, как скоро:

servers.txt

 SERVERNAME1;11,65,73
SERVERNAME2;1
SERVERNAME3;1,2,3,4,5
SERVERNAME4;
SERVERNAME5;
SERVERNAME5;33,64,217,15
  

Обратите ; внимание на отсутствие идентификаторов в конце имени СЕРВЕРА 4 , и 5 это приведет к поиску всех событий.

Затем используйте следующий код, чтобы выбрать идентификатор события и имена серверов servers.txt и выполнить соответствующий поиск.

 $body = Get-Content $computers | ForEach-Object {

    # Reset Variables
    $EventIds=$ServerName=$split=$null

    # Split the line in the text file on ;
    $split = $_ -split ";"

    # Get the servernamne and eventIds
    $ServerName = $split[0]
    [Array]$EventIds = $split[1] -split ','

    # If there is an event id mentioned search for it else search for all events
    If($EventIds -ne "" -and $EventIds -ne $null){
        Get-WinEvent -ComputerName $ServerName -FilterHashtable @{logname=$logname; Level=1,2,3; starttime=$StartDate; Id=$EventIds} -ErrorAction SilentlyContinue
    }
    Else{
        Get-WinEvent -ComputerName $ServerName -FilterHashtable @{logname=$logname; Level=1,2,3; starttime=$StartDate}    
    }
}
  

Комментарии:

1. Это может сработать. Однако я должен отметить 2 вещи: набор идентификаторов событий, которые я собираюсь фильтровать, идентичен для всех серверов, и если процесс не увидел ни одной записи из набора идентификаторов, процесс завершится и больше не будет искать.

2. @lapsantos Я добавил дополнительный цикл foreach для поиска каждого идентификатора по одному. Так что, если у идентификатора нет какого-либо события, он автоматически перейдет к следующему идентификатору.

3. @lapsantos оказывается, вам не нужен цикл foreach, который вы можете просто использовать -ErrorAction SilentlyContinue с массивом идентификаторов событий, и он продолжит поиск. Я обновил свой ответ, чтобы отразить это.

4. Спасибо за помощь, Ричард. Я поддержал ваш ответ. 🙂

Ответ №2:

Я действительно решил эту проблему, просто добавив строку кода.

Добавлено это $EventID = Get-Content 'EventID.txt'

и изменил это

 $body = Get-Content $computers | ForEach-Object {
    Get-WinEvent -ComputerName $_ -FilterHashtable @{logname=$logname; Level=1,2,3; starttime=$StartDate; ID=$EventID}    
}