Есть ли способ динамически фильтровать Eventlog? - PullRequest
0 голосов
/ 25 марта 2019

Я пытаюсь написать сценарий PowerShell, который выполняется событием. Этот скрипт PowerShell должен запустить:

Get-WinEvent -FilterHashtable @{Logname='security';ID=$instanceID} -MaxEvents 1

чтобы получить Событие, которое вызвало сценарий PS.

Пока все хорошо, как только у меня будет это событие, я хочу отправить электронное письмо. Это письмо должно содержать некоторый контент из сообщения о событии.

Например: событие с кодом 4720 (была создана учетная запись пользователя) Учетная запись пользователя xx была создана xx во время xx.

Теперь у меня есть около 10 идентификаторов событий, на которые я хочу ответить по электронной почте. Эти идентификаторы событий имеют различия в сообщении.

Есть ли динамический способ сделать это?

Я попробовал следующее:

param(
    [Parameter(Mandatory = $true)]$instanceID
)

#$instanceIDs = @(4661,4662,5139,5136,5137,5138,5139,5141,4720,4722,4723,4724,4725,4726,4738,4740,4767,4780,4781,4794,5376,5377,4741,4742,4743,4727,4728,4729)
$event = Get-WinEvent -FilterHashtable @{Logname='security';ID=$instanceID} -MaxEvents 1


Function EventIDxxx{
    Get-WinEvent -FilterHashtable @{Logname='security';ID=$instanceID} -MaxEvents 1 |
        Select-Object -Property timecreated,
        @{label='username';expression={$_.properties[0].value}},
        @{label='computername';expression={$_.properties[1].value}}
}

Но я должен создать для каждого события новую функцию. У кого-нибудь есть идея?

Большое спасибо


** Редактировать **

Я хотел бы иметь скрипт Powershell, который считывает сообщение о событии и записывает нужные мне части в переменные.

A user account was created.

Subject:
    Security ID:        Contoso\Conlil
    Account Name:       Conlil
    Account Domain:     Contoso
    Logon ID:       0x1468731E

New Account:
    Security ID:        Contoso\ASD
    Account Name:       ASD
    Account Domain:     Contoso

Attributes:
    SAM Account Name:   ASD
    Display Name:       wSDSAD D. DSA
    User Principal Name:    ASD@Contoso.com
    Home Directory:     -
    Home Drive:     -
    Script Path:        -
    Profile Path:       -
    User Workstations:  -
    Password Last Set:  <never>
    Account Expires:        <never>
    Primary Group ID:   513
    Allowed To Delegate To: -
    Old UAC Value:      0x0
    New UAC Value:      0x15
    User Account Control:   
        Account Disabled
        'Password Not Required' - Enabled
        'Normal Account' - Enabled
    User Parameters:    -
    SID History:        -
    Logon Hours:        <value not set>

Additional Information:
    Privileges      -

Например, в этом событии я хочу иметь 1. Имя пользователя и домен создателя 2. Название созданной учетной записи 3. Домен созданного аккаунта 4. Электронная почта созданного аккаунта 5. Может быть, HomeDrive 6. Элементы управления учетной записью пользователя

Я мог бы сделать это с помощью следующего кода:

@{label='Username';expression={$_.properties[x].value}},

Но это было бы статично, и мне нужно создавать для каждого события новую функцию.

Ответы [ 3 ]

1 голос
/ 25 марта 2019

В качестве альтернативы вашему сценарию (подходу) вы можете прикрепить задачу Windows к этому событию с помощью средства просмотра событий:

Щелкните правой кнопкой мыши на событии, затем нажмите «Прикрепить задачу к этому событию…»,Затем у вас есть несколько вариантов, например, вы можете запустить программу (это может быть powershell.exe) или отправить электронное письмо.

Ссылка: https://blogs.technet.microsoft.com/wincat/2011/08/25/trigger-a-powershell-script-from-a-windows-event/

ОБНОВЛЕНИЕ

Мой плохой "отправка электронной почты из события задачи" устарел .

Другой вариант - создать задачу, запустить ее с помощью powershell.exe и передать какаргумент сценарий, который вызывает командлет Send-MailMessage: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-5.1

0 голосов
/ 28 марта 2019

Я получил свой ответ.

$event = Get-WinEvent -FilterHashtable @{Logname='security';ID=$instanceID} -MaxEvents 1

foreach($entry in $event){
    #Get the XML...
    $XML = [xml]$entry.ToXml()

    #Some events use other nodes, like 'UserData' on Applocker events...
    $XMLData = $null
    if( $XMLData = @( $XML.Event.EventData.Data )) {
        For( $i=0; $i -lt $XMLData.count; $i++ ) {
            #We don't want to overwrite properties that might be on the original object, or in another event node.   
            Add-Member -InputObject $entry -MemberType NoteProperty -name "EventData$($XMLData[$i].name)" -Value $XMLData[$i].'#text' -Force
        }
    }
}

$entry | select EventData*
0 голосов
/ 26 марта 2019

Это то, для чего рассчитаны потребители / наблюдатели событий WMI .Вы можете установить временные или постоянные единицы.

Это очень распространенная вещь, и во всем Интернете есть примеры того, как ее настроить, и даже готовые сценарии, которые можно использовать по мере необходимости или настраивать по мере необходимости.

Powershell Centralized Log Monitor

Контролирует набор серверов для указанных событий журнала и отправляет оповещения по электронной почте, когда получает отслеживаемые события.

## Powershell Log Monitor Script ## 
## Contributing authors - mck74,mjolinor, 

param([switch]$ShowEvents = $false,[switch]$NoEmail = $false,[switch]$useinstanceid = $false) 


$log = "Application" 
$hist_file = $log + "_loghist.xml" 
$seed_depth = 200 

#run interval in minutes - set to zero for runonce, "C" for 0 delay continuous loop. 
$run_interval = 1 

$EmailFrom = "<user@domain.tld>" 
$EmailTo = "<user@domain.tld>" 
$EmailSubject = "Server event notification"   

$SMTPServer = "smtphost.domain.tld" 
$SMTPAuthUsername = "username" 
$SMTPAuthPassword = "password" 

$computers = @(gc monitored_computers.txt) 
$event_list = @{} 
Import-Csv alert_events.csv |% {$event_list[$_.source + '#' + $_.id] = 1} 


#see if we have a history file to use, if not create an empty $histlog 
if (Test-Path $hist_file){$loghist = Import-Clixml $hist_file} 
 else {$loghist = @{}} 


$timer = [System.Diagnostics.Stopwatch]::StartNew() 

function send_email { 
$mailmessage = New-Object system.net.mail.mailmessage  
$mailmessage.from = ($emailfrom)  
$mailmessage.To.add($emailto) 
$mailmessage.Subject = $emailsubject 
$mailmessage.Body = $emailbody 
$mailmessage.IsBodyHTML = $true 
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)   
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("$SMTPAuthUsername", "$SMTPAuthPassword")  
$SMTPClient.Send($mailmessage) 
} 
#START OF RUN PASS 
$run_pass = { 

$EmailBody = "Log monitor found monitored events. `n" 

$computers |%{ 
$timer.reset() 
$timer.start() 

Write-Host "Started processing $($_)" 

#Get the index number of the last log entry 
$index = (Get-EventLog -ComputerName $_ -LogName $log -newest 1).index 

#if we have a history entry calculate number of events to retrieve 
#   if we don't have an event history, use the $seed_depth to do initial seeding 
if ($loghist[$_]){$n = $index - $loghist[$_]} 
 else {$n = $seed_depth} 

if ($n -lt 0){ 
 Write-Host "Log index changed since last run. The log may have been cleared. Re-seeding index." 
 $events_found = $true 
 $EmailBody += "`n Possible Log Reset $($_)`nEvent Index reset detected by Log Monitor`n" | ConvertTo-Html 
 $n = $seed_depth 
 } 

Write-Host "Processing $($n) events." 

#get the log entries 

if ($useinstanceid){ 
$log_hits = Get-EventLog -ComputerName $_ -LogName $log -Newest $n | 
? {$event_list[$_.source + "#" + $_.instanceid]} 
} 

else {$log_hits = Get-EventLog -ComputerName $_ -LogName $log -Newest $n | 
? {$event_list[$_.source + "#" + $_.eventid]} 
} 

#save the current index to $loghist for the next pass 
$loghist[$_] = $index 

#report number of alert events found and how long it took to do it 
if ($log_hits){ 
 $events_found = $true 
 $hits = $log_hits.count 
 $EmailBody += "`n Alert Events on server $($_)`n" 
 $log_hits |%{ 
  $emailbody += "<br><br>" 
  $emailbody += $_ | select MachineName,EventID,Message | ConvertTo-Html  
 $emailbody += "<br><br>" 
 } 
 } 
 else {$hits = 0} 
$duration = ($timer.elapsed).totalseconds 
write-host "Found $($hits) alert events in $($duration) seconds." 
"-"*60 
" " 
if ($ShowEvents){$log_hits | fl | Out-String |? {$_}} 
} 

#save the history file to disk for next script run  
$loghist | export-clixml $hist_file 

#Send email if there were any monitored events found 
if ($events_found -and -not $NoEmail){send_email} 

} 
#END OF RUN PASS 

Write-Host "`n$("*"*60)" 
Write-Host "Log monitor started at $(get-date)" 
Write-Host "$("*"*60)`n" 

#run the first pass 
$start_pass = Get-Date 
&$run_pass 

#if $run_interval is set, calculate how long to sleep before the next pass 
while ($run_interval -gt 0){ 
if ($run_interval -eq "C"){&$run_pass} 
 else{ 
 $last_run = (Get-Date) - $start_pass 
 $sleep_time = ([TimeSpan]::FromMinutes($run_interval) - $last_run).totalseconds 
 Write-Host "`n$("*"*10) Sleeping for $($sleep_time) seconds `n" 

#sleep, and then start the next pass 
 Start-Sleep -seconds $sleep_time 
 $start_pass = Get-Date  
 &$run_pass 
 } 
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...