首页 > 解决方案 > 如何从多台计算机收集和发送特定事件 ID(过去 24 小时)并作为电子邮件发送?

问题描述

我需要从多个服务器获取过去 24 小时内事件ID 为 4202、4204、4206、4208、4212的电子邮件警报。

如何使用下面仅适用于本地计算机的 Powershell 来获得它?

脚本:

$HtmlHead = @"
<style>
    body {
        font-family: Arial;
    }
    table {
        width: 100%;
        border-collapse: collapse;
        border: 1px solid;
    }
    th {
        background-color: green;
        border: 1px solid;
        padding: 1px;
    }
    td {
        border: 1px solid;
        padding: 1px;
    }
</style>
"@

$mailArgs = @{
    SmtpServer  = 'mail.domain.com'
    From        = 'SystemAdmin@domain.com'
    To          = 'Manager@domain.com'
    Subject     = '{0} DFS report'
    Attachments = 'C:\Logs\DFS-Events_{0}.csv'
}

$EventIDs = 4202, 4204, 4206, 4208, 4212

Get-DfsrMember | Select-Object -ExpandProperty ComputerName -Unique | Sort-Object | ForEach-Object {
    Write-Host "Processing $($_) ..."
    Try
    {
        $splat = $mailArgs.psobject.Copy()
        $splat['Attachments'] = $splat['Attachments'] -f $_
        Get-WinEvent -FilterHashTable @{ LogName = 'System'; StartTime = (Get-Date).AddHours(-24); ID = $EventIDs } |
        Select-Object -Property TimeCreated, Id, Message |
        Sort-Object -Property TimeCreated |
        Export-Csv -NoTypeInformation -UseCulture -Path $splat['Attachments']
        $splat['Body'] = "$($_) DFS Replication Related Events | ForEach-Object { "$($upTime.$_) $_" })"
    }
    Catch
    {
        Write-Error -ErrorRecord $_
        $splat['Body'] = "$($_) query failed:`r`n$($_.Exception.Message)"
        $splat.Remove('Attachments')
    }
    # Send the result for each server as email
    $splat['Subject'] = $splat['Subject'] -f $_
    Send-MailMessage @splat
}

标签: powershell

解决方案


我认为您只需要第二个循环即可通过所有计算机。

改变

$ComputerName = Get-DfsrMember | ...

进入

$computers = Get-DfsrMember | ...

然后将ForEach ( $LogType in $Logs ) { ... }循环包装在另一个循环中,例如

foreach ( $computerName in $computers ) {
    foreach ( $LogType in $Logs ) {
        ..
    }
}

PS我喜欢用小写字母foreach ($thingy in $collection) {}和驼峰字母$collection | ForEach-Object {}来帮助可视化两者之间的区别


根据您的评论,结果也应该在电子邮件的 HTML 表格中。

为此,添加BodyAsHtml = $true您的 $mailArgs 哈希表并捕获调用结果,Get-WinEvent以便您可以导出为 CSV,然后转换为一个漂亮的 HTML 表。

您的代码对此进行了轻微调整:

$HtmlHead = @"
<style>
    body {
        font-family: Arial;
    }
    table {
        width: 100%;
        border-collapse: collapse;
        border: 1px solid;
    }
    th {
        background-color: green;
        border: 1px solid;
        padding: 1px;
    }
    td {
        border: 1px solid;
        padding: 1px;
    }
</style>
"@

$mailArgs = @{
    SmtpServer  = 'mail.domain.com'
    From        = 'SystemAdmin@domain.com'
    To          = 'Manager@domain.com'
    Subject     = '{0} DFS report'
    Attachments = 'C:\Logs\DFS-Events_{0}.csv'
    BodyAsHtml  = $true
}

$EventIDs = 4202, 4204, 4206, 4208, 4212

Get-DfsrMember | Select-Object -ExpandProperty ComputerName -Unique | Sort-Object | ForEach-Object {
    Write-Host "Processing $($_) ..."
    Try
    {
        $splat = $mailArgs.psobject.Copy()
        $splat['Attachments'] = $splat['Attachments'] -f $_
    
        $result = Get-WinEvent -FilterHashTable @{ LogName = 'System'; StartTime = (Get-Date).AddHours(-24); ID = $EventIDs } -ErrorAction Stop |
                    Select-Object -Property TimeCreated, Id, Message |
                    Sort-Object -Property TimeCreated
        # export to csv file
        $result | Export-Csv -NoTypeInformation -UseCulture -Path $splat['Attachments']
        # create the HTML body
        $splat['Body'] = ($result | ConvertTo-Html -Head $HtmlHead -PreContent "<h3>$($_) DFS Replication Related Events</h3>")
    }
    Catch
    {
        Write-Error -ErrorRecord $_
        # don't forget you're sending HTML, so use "<br />" instead of "`r`n"
        $splat['Body'] = "$($_) query failed:<br />$($_.Exception.Message)"
        $splat.Remove('Attachments')
    }
    # Send the result for each server as email
    $splat['Subject'] = $splat['Subject'] -f $_
    Send-MailMessage @splat
}

推荐阅读