使用PowerShell监视日志文件 - 解析数据

时间:2016-06-02 19:42:51

标签: windows powershell

我是脚本和PowerShell的新手。

我已设法设置一个检查服务器日志文件的脚本,然后向我发送一封电子邮件,其中包含一行显示用户未能在日志中登录的行。日志文件包含在每行中包含此信息的数据行:

date&time        Login.Success(or Login.Failure)        IP        Username

有没有办法检查当天的日志文件我可以解析数据,以便不是每次向login.failure用户发送电子邮件,它可以比较文件中的每一行,看看是否该用户还有一个login.success并从最终列表中删除这些用户(这样我最终只得到用户最终无法登录的事件列表)?

现在我收到一个登录失败的用户列表,但我只能告诉他们他们尝试连续5次登录失败,但是如果他们在第6次试图成功登录成功则没有。我想要一个仅登录失败的用户列表。

2 个答案:

答案 0 :(得分:0)

我创建了一些示例数据并将其保存到文本文件中:

date&time        Login.Failure        192.168.2.1        Asterix
date&time        Login.Failure        192.168.2.1        Asterix
date&time        Login.Failure        192.168.2.2        Oberlix
date&time        Login.Failure        192.168.2.3        Siegfried
date&time        Login.Failure        192.168.2.3        Siegfried
date&time        Login.Success        192.168.2.3        Siegfried
date&time        Login.Failure        192.168.2.4        Siegfried
date&time        Login.Failure        192.168.2.4        Michael
date&time        Login.Failure        192.168.2.5        Michael

要解析它们,我使用Get-Content cmdlet读取该文件并创建PSCustomObject foreach行:

$parsedResult = Get-Content 'your_log_file.txt' | ForEach-Object {
    $record = $_ -split '\s{2,}'
    [PSCustomObject]@{
        DateTime = $record[0]
        Login = $record[1]
        IP = $record[2]
        Username = $record[3]
    }    
}

现在我有一个可用于过滤的对象数组($parsedResult)。如果我只打印它,它看起来像:

DateTime  Login         IP          Username 
--------  -----         --          -------- 
date&time Login.Failure 192.168.2.1 Asterix  
date&time Login.Failure 192.168.2.1 Asterix  
date&time Login.Failure 192.168.2.2 Oberlix  
date&time Login.Failure 192.168.2.3 Siegfried
date&time Login.Failure 192.168.2.3 Siegfried
date&time Login.Success 192.168.2.3 Siegfried
date&time Login.Failure 192.168.2.4 Siegfried
date&time Login.Failure 192.168.2.4 Michael  
date&time Login.Failure 192.168.2.5 Michael 

要过滤所有成功登录的用户,我创建了一个列表:

$userToExclude =  @($parsedResult | Where-Object Login -eq 'Login.Success' | select -expand UserName)

在此示例中,它仅包含Siegfried

现在排除列表中的所有用户:

$parsedResult | Where-Object Username -NotIn $userToExclude

输出:

DateTime  Login         IP          Username
--------  -----         --          --------
date&time Login.Failure 192.168.2.1 Asterix 
date&time Login.Failure 192.168.2.1 Asterix 
date&time Login.Failure 192.168.2.2 Oberlix 
date&time Login.Failure 192.168.2.4 Michael 
date&time Login.Failure 192.168.2.5 Michael 

您也可以对此进行分组:

$parsedResult | Where-Object Username -NotIn $userToExclude | Group-Object Username -NoElement

得到这样的东西:

Count Name                     
----- ----                     
    2 Asterix                  
    1 Oberlix                  
    2 Michael 

答案 1 :(得分:0)

如果您在对象中有数据,则可以在没有成功的用户名上进行分组

c:\ temp \ file.log

的内容
2016-06-02T15:06:59 Login.Success   127.0.0.1   user1
2016-06-02T15:06:59 Login.Failure   127.0.0.1   user1
2016-06-02T15:06:59 Login.Success   127.0.0.1   user2
2016-06-02T15:06:59 Login.Failure   127.0.0.1   user3

示例脚本

$a = ipcsv c:\temp\file.log -delim "`t" -header date, login, ip, username

$a | group username | ? {($_.group.login | Out-String) -NotMatch 'success|logout'}

*编辑:看到您的评论和屏幕截图后,试试这个

$results = ipcsv c:\temp\file.log -delim "`t" | group username | ? {($_.group.login | Out-String) -NotMatch 'success|logout'} | % {$_.group | sort {date $_.'date/time'} -Descending | select -f 1} | % {$_ | fl * | out-string}

然后在您的电子邮件中使用$results作为-body