使用 PowerShell 根据时间范围在应用程序日志中搜索字符串

使用 PowerShell 根据时间范围在应用程序日志中搜索字符串

更新日期:2022 年 10 月 11 日

我添加了时间范围参数,但收到空主体的错误消息。如何避免这种情况?

这是我当前的脚本:

$Subject = "EventLogAlert {0:yyyy-MM-dd HH:mm:ss} on $env:COMPUTERNAME" -f (Get-Date)

$Server = "smtp.server" 
$From = "[email protected]" 


$To = "[email protected]"
$Pwd = ConvertTo-SecureString "******" -AsPlainText –Force

#(Warning! Use a very restricted account for the sender, because the password stored in the script will be not encrypted)
$Cred = New-Object System.Management.Automation.PSCredential("[email protected]" , $Pwd)

$encoding = [System.Text.Encoding]::UTF8


$EndTime = Get-Date
$StartTime = (Get-Date).AddMinutes(-15)


$events    = Get-WinEvent -FilterHashtable @{LogName="Application";ID=400;ProviderName="ProviderNameGoesHere";StartTime=$StartTime;EndTime=$EndTime} |
             Where-Object {$_.Message -like '*StingToLookFor*'} |
             Select-Object -Property TaskDisplayName,ID,TimeCreated,Message -First 1


$Body = $events

Send-MailMessage -From $From -To $To -SmtpServer $Server -Body "$Body"  -Subject $Subject -Credential $Cred -Encoding $encoding

错误信息:

At C:\ps\script_name:1 char:1

+ script name: script_name.ps1

+ ~~~~~~

    + CategoryInfo          : ObjectNotFound: (script:String) [], CommandNotFoundException

    + FullyQualifiedErrorId : CommandNotFoundException

Get-WinEvent : No events were found that match the specified selection criteria.

At C:\ps\script_name.ps1:22 char:14

+ ... events    = Get-WinEvent -FilterHashtable @{LogName="Application";ID= ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (:) [Get-WinEvent], Exception

    + FullyQualifiedErrorId : NoMatchingEventsFound,Microsoft.PowerShell.Commands.GetWinEventComm

   and

Send-MailMessage : Cannot validate argument on parameter 'Body'. The argument is null or empty.

Provide an argument that is not null or empty, and then try the command again.

At C:\ps\script_name.ps1:29 char:64

+ ... Message -From $From -To $To -SmtpServer $Server -Body "$Body"  -Subje ...

+                                                           ~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationExce

   ption

    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.Send

   MailMessage

原始帖子 2022 年 10 月 10 日

我是 PowerShell 新手。我正在开发一个脚本来监视应用程序日志中的特定字符串。下面的脚本可以工作,但我需要帮助限制搜索的时间范围。现在它搜索整个日志。我只想搜索过去 15 分钟,并且只有在此时间范围内有匹配项时才发送电子邮件。该脚本通过任务计划程序每 10 分钟运行一次。

有人可以指导我解决这个问题吗?

#Mail SMTP Setup Section
$Subject = "EventLogAlert {0:yyyy-MM-dd HH:mm:ss} on $env:COMPUTERNAME" -f (Get-Date)
$Server = "smtp.server" 
$From = "[email protected]" 

$To = "[email protected]"
$Pwd = ConvertTo-SecureString "enterpassword" -AsPlainText –Force password
$Cred = New-Object System.Management.Automation.PSCredential("[email protected]" , $Pwd) #Sender account credentials

$encoding = [System.Text.Encoding]::UTF8 


$events    = Get-WinEvent -FilterHashtable @{LogName="Application";ID=400;ProviderName="ProviderNameGoesHere"} | 
             Where-Object {$_.Message -like '*StingToLookFor*'} | 
             Select-Object -Property TaskDisplayName,ID,TimeCreated,Message



$Body=Get-WinEvent -FilterHashtable @{LogName="Application";ID=400;ProviderName='ProviderNameGoesHere'} | Select TimeCreated,Message | select-object -First 1


Send-MailMessage -From $From -To $To -SmtpServer $Server -Body "$Body"  -Subject $Subject -Credential $Cred -Encoding $encoding

答案1

您可以将此代码添加到脚本中,以设置开始时间、结束时间以及将它们传递到 get-winevent。

$EndTime = Get-Date
$StartTime = (Get-Date).AddMinutes(-15)

Get-WinEvent -FilterHashtable @{LogName="Application";ID=400;ProviderName='ProviderNameGoesHere';StartTime=$StartTime;EndTime=$EndTime} | Select TimeCreated,Message | select-object -First 1

编辑:使用 try/catch 解决注释问题。现在,当 get-winevent 在过去 15 分钟内没有结果时,它只会打印没有结果,而不会在控制台中发送电子邮件。如果您希望它仍然发送一封电子邮件说明没有事件,则将 send-mailmessage 行粘贴到 write-host 所在的 catch 块中,并将“$body”更改为仅显示“无结果”

$Subject = "EventLogAlert {0:yyyy-MM-dd HH:mm:ss} on $env:COMPUTERNAME" -f (Get-Date)

$Server = "smtp.server" 
$From = "[email protected]" 


$To = "[email protected]"
$Pwd = ConvertTo-SecureString "******" -AsPlainText –Force

#(Warning! Use a very restricted account for the sender, because the password stored in the script will be not encrypted)
$Cred = New-Object System.Management.Automation.PSCredential("[email protected]" , $Pwd)

$encoding = [System.Text.Encoding]::UTF8


$EndTime = Get-Date
$StartTime = (Get-Date).AddMinutes(-15)


try { 
        $events    = Get-WinEvent -FilterHashtable @{LogName="Application";ID=400;ProviderName="ProviderNameGoesHere";StartTime=$StartTime;EndTime=$EndTime} |
                    Where-Object {$_.Message -like '*StingToLookFor*'} |
                    Select-Object -Property TaskDisplayName,ID,TimeCreated,Message -First 1
        $Body = $events

        Send-MailMessage -From $From -To $To -SmtpServer $Server -Body "$Body"  -Subject $Subject -Credential $Cred -Encoding $encoding
    }
catch [Exception] {
        if ($_.Exception -match "No events were found that match the specified selection criteria") {
        Write-Host "No events found in last 15 minutes - not sending email.";
                 }
    }

答案2

Narzard 的答案涵盖了这一点,但按相对时间搜索的另一种方法是使用 xml XPath(您可以从事件查看器过滤器中复制/粘贴):

Get-WinEvent -LogName Application -FilterXPath @'
<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[
      EventID=400 and
      Provider[@Name='ProviderNameGoesHere'] and 
      TimeCreated[timediff(@SystemTime) &lt;= 900000]]]
    </Select>
  </Query>
</QueryList>
'@ 

XPath 比较冗长,但可以搜索事件数据属性,例如用户名

相关内容