PowerShell Select-String查找最新的日志文件条目

时间:2013-10-16 03:43:26

标签: powershell

让我简单说一下:

我在AD中有几台机器需要经常检查。我是PowerShell的新手,并寻找一种实现它的工作方式。

需要检查什么?远程系统上的某些文件,我们称之为File1.log(它的名字在每台机器上都是一样的)。该文件包含多行,如下所示:

15.10.2013 23:38:54 | FA OK 98.9 USD

我需要知道过去2小时或24小时内有多少条目,具体取决于检查时间。 (“FA OK”表达式正常)并在最后一行获得金额。

我已经设法做了: 使用$ checktime2 =(Get-Date).AddHours(-2).ToString(“dd.MM.yyyy HH”)[匹配格式化]。该脚本只生成空文件,尽管测试文件中的条目正确...代码看起来很糟糕,但我不知道如何检查不同的小时。在我看来,AddHours()不接受括号中的变量或我只是不知道如何设置它。问题在这里 - 谷歌建议我Select-String可以接受多个不同的值(使用OR,而不是AND逻辑运算符)。我不确定这里有什么问题以及如何继续前进。脚本有效并且不报告错误。任何关于如何使这个脚本工作或至少清理它的反馈都是非常受欢迎的。提前谢谢!

$title = "Check"
$message = "2 or 24 hours back?"
$checktime0 = (Get-Date).AddHours(0).ToString("dd.MM.yyyy HH")
$checktime1 = (Get-Date).AddHours(-1).ToString("dd.MM.yyyy HH")
$checktime2 = (Get-Date).AddHours(-2).ToString("dd.MM.yyyy HH")
$checktime3 = (Get-Date).AddHours(-3).ToString("dd.MM.yyyy HH")
$checktime4 = (Get-Date).AddHours(-4).ToString("dd.MM.yyyy HH")
$checktime5 = (Get-Date).AddHours(-5).ToString("dd.MM.yyyy HH")
$checktime6 = (Get-Date).AddHours(-6).ToString("dd.MM.yyyy HH")
$checktime7 = (Get-Date).AddHours(-7).ToString("dd.MM.yyyy HH")
$checktime8 = (Get-Date).AddHours(-8).ToString("dd.MM.yyyy HH")
$checktime9 = (Get-Date).AddHours(-9).ToString("dd.MM.yyyy HH")
$checktime10 = (Get-Date).AddHours(-10).ToString("dd.MM.yyyy HH")
$checktime11 = (Get-Date).AddHours(-11).ToString("dd.MM.yyyy HH")
$checktime12 = (Get-Date).AddHours(-12).ToString("dd.MM.yyyy HH")
$checktime13 = (Get-Date).AddHours(-13).ToString("dd.MM.yyyy HH")
$checktime14 = (Get-Date).AddHours(-14).ToString("dd.MM.yyyy HH")
$checktime15 = (Get-Date).AddHours(-15).ToString("dd.MM.yyyy HH")
$checktime16 = (Get-Date).AddHours(-16).ToString("dd.MM.yyyy HH")
$checktime17 = (Get-Date).AddHours(-17).ToString("dd.MM.yyyy HH")
$checktime18 = (Get-Date).AddHours(-18).ToString("dd.MM.yyyy HH")
$checktime19 = (Get-Date).AddHours(-19).ToString("dd.MM.yyyy HH")
$checktime20 = (Get-Date).AddHours(-20).ToString("dd.MM.yyyy HH")
$checktime21 = (Get-Date).AddHours(-21).ToString("dd.MM.yyyy HH")
$checktime22 = (Get-Date).AddHours(-22).ToString("dd.MM.yyyy HH")
$checktime23 = (Get-Date).AddHours(-23).ToString("dd.MM.yyyy HH")
$checktime24 = (Get-Date).AddHours(-24).ToString("dd.MM.yyyy HH")
$2 = New-Object System.Management.Automation.Host.ChoiceDescription "&A", `
"Check for 2 hours back"
$24 = New-Object System.Management.Automation.Host.ChoiceDescription "&B", `
"Check for 24 hours back"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($2, $24)

$result = $host.ui.PromptForChoice($title, $message, $options, 0)

switch ($result){ 
0   {Get-Content File1.log | Select-String '($checktime2|$checktime1|$checktime0)' | Select-String "FA OK" |  measure-object -line | out-file OPTcheck.txt -Append
Get-Content File1.xjou | Select-String '($checktime2|$checktime1|$checktime0)' | Select-String "FA OK" | select -Last 1 | out-file OPTcheck.txt -Append
}
1   {Get-Content File1.log| Select-String '($checktime24|$checktime23|$checktime22|$checktime21|$checktime20|$checktime19|$checktime18|$checktime17|$checktime16|$checktime15|$checktime14|$checktime13|$checktime12|$checktime11|$checktime10|$checktime9|$checktime8|$checktime7|$checktime6|$checktime5|$checktime4|$checktime3|$checktime2|$checktime1|$checktime0)' | Select-String "FA OK" |  measure-object -line | out-file OPTcheck.txt -Append
Get-Content File1.log | Select-String $checktime24 | Select-String "FA OK" | select -Last 1 | out-file OPTcheck.txt -Append
}
default {Get-Credential} //used to catch the error in switch
}

3 个答案:

答案 0 :(得分:2)

从头开始:

$line = "15.10.2013 23:38:54|FA OK 98.9 USD"
$adate= [datetime]::ParseExact(($line.Split('|')[0]),"dd.MM.yyyy HH:mm:ss",$null)

然后您可以使用以下方法检查日期是否在两个日期之间:

($adate -le ([datetime]::Now).AddHours(-1) -and $adate -gt ([datetime]::Now).AddHours(-2))

之后你只需要一个if结构。

答案 1 :(得分:1)

假设日期的格式适合您的语言环境,则以下代码可能会有所帮助吗?你可以像这样运行它:

Check for entries two hours back or newer:

PS1> .\Get-File1.ps1 -Path \\srver\share\file1.log -Two

or check for entries twentyfour hours back or newer

PS1> .\Get-File1.ps1 -Path \\srver\share\file1.log -Twenty   

or check since a specified time back

PS1> .\Get-File1.ps1 -Path \\srver\share\file1.log -Since "15.10.2013 05:05"

以下是代码

# Get-File1.ps1
#
param([string] $Path, [DateTime] $Since, [switch] $Two, [switch] $TwentyFour);

if ($Two) {
   $Since = $(Get-Date).AddHours(-2);
}
if ($TwentyFour) {
   $Since = $(Get-Date).AddHours(-24);
}   

gc $Path | %{
   $sDate, $status = $_.Split('|');
   $date = Get-Date $sDate;
   if ($date -ge $Since -and $Status -match "^FA OK" ) {
      $_;
   }
}

希望这会有所帮助 / fridden

答案 2 :(得分:0)

我设法按照我的要求或多或少地运行。

答案下方:

目前,我有15个网络路径来检查最新更新。

$Path1 = "\\path-to-the-jou-file-for-2h-check\joufile.jou"
$Path2 = "\\path-to-the-jou-file-for-24h-check\joufile.jou"

我定义了2h和24h Get-Date别名。根据我的需要,我必须检查$ Path2文件中的昨天条目,并检查$ path1当前小时,最后一小时和2小时前。

$npath = path-to-my-output-file
$date24 = (Get-Date).AddHours(-24).ToString("dd.MM.yyyy")
$date2 = (Get-Date).AddHours(-2).ToString("dd.MM.yyyy HH")
$date1 = (Get-Date).AddHours(-1).ToString("dd.MM.yyyy HH")
$date0 = (Get-Date).AddHours(0).ToString("dd.MM.yyyy HH")

是的,我知道这是矫枉过正的,我确实为化妆品添加了“AddHours(0)”:-)如您所见,我将输出值转换为所需的格式,以便稍后我可以将它用于-pattern。

对于到目前为止检查2小时的每个对象。如您所见,我必须使用-pattern参数来匹配“OR”逻辑语句中的多个值:

Get-Content $Path1| Select-String -Pattern $date2, $date1, $date0 | Select-String "FA OK" | Measure-Object -line | out-file $npath -Append
Get-Content $Path1 | Select-String -Pattern $date2, $date1, $date0 | Select-String "FA  OK" | Select -last 1 | out-file $npath -Append
Get-Content $1076 | Select-String -Pattern $date2, $date1, $date0 | Select-String "Status now" | Select -last 1 | out-file $npath -Append

24小时时间范围的差异在于我只修改了.ToString值,以便更改日志文件条目中要查找的日期。日志滚动时会出现问题,但它会在2个月内发生一次,因此没有太大问题。如果脚本是完美的,那么值得实现,但它确实起作用。

我想感谢你们看过这个问题并提供了一些意见,这对于在PowerShell中实现实际节省时间的第一步有很大帮助。 : - )

谢谢!

Koliat