PowerShell 脚本向我发送事件查看器的电子邮件警报 errors/warnings/failures

PowerShell script to send me email alerts of Event Viewer errors/warnings/failures

我正在尝试编辑下面的脚本以利用任务计划程序,每次在我们的服务器事件查看器中记录 error/warning/failure 时都会向我发送电子邮件通知。

重要信息:

在此先感谢您的帮助。这是来自 https://github.com/blachniet/blachniet-psutils/blob/master/Send-EventEntryEmail.psm1 的脚本:

Import-Module $PSScriptRoot\Send-EventEntryEmail.psm1

Function Send-EventEntryEmail {

[CmdletBinding()]
    param(
        [Parameter()]
        [string] $LogName = "System""Application""Security,
    
        [Parameter(Mandatory=$true)]
        [string] $Source,
    
        [Parameter()]
        [int] $Newest = 5,

        [Parameter()]
        [string[]] $EntryType = "Error""Warning""Failure",
    
        [Parameter(Mandatory=$true)]
        [string] $SmtpUser = "helpdesk@mydomain.com",
    
        [Parameter(Mandatory=$true)]
        [string] $SmtpPassword = "passwordexample",
    
        [Parameter()]
        [int] $SmtpPort = 587,
    
        [Parameter()]
        [string] $SmtpServer = "smtp.mail.outlook.com",
    
        [Parameter(Mandatory=$true)]
        [string] $MailFrom = "helpdesk@mydomain.com",
    
        [Parameter(Mandatory=$true)]
        [string] $MailTo = "myemail@mydomain.com,
    
        [Parameter()]
        [string] $Subject = "EventLogAlert",

    )

    # Get the event entries.
    $eventEntries = Get-EventLog -LogName $LogName -Source $Source -Newest $Newest -EntryType $EntryType

    # Create a table row for each entry.
    $rows = ""
    foreach ($eventEntry in $eventEntries){
        $rows += @"
        <tr>
            <td style="text-align: center; padding: 5px;">$($eventEntry.TimeGenerated)</td>
            <td style="text-align: center; padding: 5px;">$($eventEntry.EntryType)</td>
            <td style="padding: 5px;">$($eventEntry.Message)</td>
        </tr>
"@
    }

    # Create the email.
    $email = New-Object System.Net.Mail.MailMessage( $MailFrom , $MailTo )
    $email.Subject = $Subject
    $email.IsBodyHtml = $true
    $email.Body = @"
    <table style="width:100%;border">
        <tr>
            <th style="text-align: center; padding: 5px;">Time</th>
            <th style="text-align: center; padding: 5px;">Type</th>
            <th style="text-align: center; padding: 5px;">Message</th>
        </tr>
    
    $rows
    </table>
"@

    # Send the email.
    $SMTPClient=New-Object System.Net.Mail.SmtpClient( $SmtpServer , $SmtpPort )
    $SMTPClient.EnableSsl=$true
    $SMTPClient.Credentials=New-Object System.Net.NetworkCredential( $SmtpUser , $SmtpPassword );
    $SMTPClient.Send( $email )
}

Export-ModuleMember Send-EventEntryEmail

以下是我在 运行 当前脚本时在 ISE 中遇到的错误:

At line:17 char:34
+         [string[]] $EntryType = "Error""Warning""Failure",
+                                  ~
Missing ')' in function parameter list.
At line:35 char:49
+         [string] $MailTo = "myemail@mydomain.com,
+                                                 ~
Missing argument in parameter list.
At line:37 char:20
+         [Parameter()]
+                    ~
An expression was expected after '('.
At line:38 char:45
+         [string] $Subject = "EventLogAlert",
+                                             ~
Missing expression after ','.
At line:3 char:31
+ Function Send-EventEntryEmail {
+                               ~
Missing closing '}' in statement block or type definition.
At line:40 char:5
+     )
+     ~
Unexpected token ')' in expression or statement.
At line:78 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList

您可以通过设置计划任务来通过电子邮件订阅事件日志,该计划任务将接收新事件的通知并通过电子邮件发送。

在任务计划程序中,您首先添加一个由“发生事件”触发的任务。要订阅特定的 Log/Source/Event ID 组合,请使用“基本”。要订阅许多事件,请使用“自定义”和满足您需要的事件过滤器。

无论哪种方式,第二步是一个 powershell 脚本,它可以检查事件并通过电子邮件转发它。这可以通过在任务计划程序中添加一个操作来完成,该操作调用 powershell.exe 并传递参数 .\MyDelightfulScriptName.ps1 -eventRecordID $(eventRecordID) -eventChannel $(eventChannel).

要访问记录的事件,powershell 脚本使用 Get-WinEventEventRecordID 过滤器:

# Collects all named paramters (all others end up in $Args)
param($eventRecordID,$eventChannel)

$event = Get-WinEvent -LogName $eventChannel -FilterXPath "<QueryList><Query Id='0' Path='$eventChannel'><Select Path='$eventChannel'>*[System[(EventRecordID=$eventRecordID)]]</Select></Query></QueryList>";

Send-MailMessage `
    -From 'evetlog@server.domain.local' `
    -To 'admin@domain.local' `
    -Subject ($event.Message.Split([Environment]::NewLine)[0]) `
    -SmtpServer 'smtp.domain.local' `
    -Body ($event.Message);

缺少非常重要的信息:创建触发器后,您需要调整任务的 XML(添加 ValueQueries)!

(导出、调整、导入)

<EventTrigger>
  <Enabled>true</Enabled>
  <Subscription> ... </Subscription>
  <ValueQueries>
    <Value name="eventRecordID">Event/System/EventRecordID</Value>
    <Value name="eventChannel">Event/System/Channel</Value>
  </ValueQueries>
</EventTrigger>

Nice-to-read:
https://docs.microsoft.com/de-de/archive/blogs/wincat/trigger-a-powershell-script-from-a-windows-event

我还调整了脚本以允许身份验证,将其调整为 UTF-8,以便 äöü 可以工作,并为主题添加了更多信息:

# Collects all named paramters (all others end up in $Args)
param($eventRecordID,$eventChannel)

$event = Get-WinEvent -LogName $eventChannel -FilterXPath "<QueryList><Query Id='0' Path='$eventChannel'><Select Path='$eventChannel'>*[System[(EventRecordID=$eventRecordID)]]</Select></Query></QueryList>";

$secpasswd = ConvertTo-SecureString "<password>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("<username>", $secpasswd)

Send-MailMessage `
    -From '<sender>' `
    -To '<receiver>' `
    -Subject "$env:COMPUTERNAME EVENTLOG $($event.Message.Split([Environment]::NewLine)[0][0..30] -join '')" `
    -SmtpServer '<server>' `
    -Credential $cred `
    -Body ($event.Message) `
    -Port 587 `
    -UseSsl `
    -Encoding UTF8;