powershell Get-Winevent SWITCH MATCH问题

时间:2014-08-15 16:39:40

标签: powershell

运行此powershell命令并将输出保存在csv中。

powershell "Get-WinEvent -EA SilentlyContinue -FilterHashtable @{Logname='System';ID=42}| SELECT-Object @{Label = 'TimeCreated'; Expression = {Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'}},@{Label = 'DayOfWeek'; Expression = {(Get-Date $_.TimeCreated).DayOfWeek}},ID,@{l='ID Description';e={Switch ($_)  { {$_.ID -eq '42'}{'Type=Sleep matched using EventID';break} {$_.MESSAGE -Match 'Sleep Reason: Application API'}{Type='Sleep matched using Message';break}  }}},MESSAGE|ConvertTo-Csv -NoTypeInformation | %{ $_ -replace """`r`n""",',' } | select -Skip 1 | Out-File -Append c:\logs\timeline\TEMP_TimeLine.csv"

我得到预期结果如下:

"2014-05-10 00:00:04","Saturday","42","Type=Sleep matched using EventID","The system is entering sleep.,,Sleep Reason: Application API"
"2014-05-09 00:00:02","Friday","42","Type=Sleep matched using EventID","The system is entering sleep.,,Sleep Reason: Application API"
"2014-05-08 00:00:02","Thursday","42","Type=Sleep matched using EventID","The system is entering sleep.,,Sleep Reason: Application API"

但是,如果我在交换机内切换两个case语句的位置,我没有得到预期的输出(派生字段' ID描述'是空白的)。我试图在消息字段和EventID字段上混合使用字符串匹配来协同工作。 这就是我正在尝试的:

powershell "Get-WinEvent -EA SilentlyContinue -FilterHashtable @{Logname='System';ID=42}| SELECT-Object @{Label = 'TimeCreated'; Expression = {Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'}},@{Label = 'DayOfWeek'; Expression = {(Get-Date $_.TimeCreated).DayOfWeek}},ID,@{l='ID Description';e={Switch ($_)  {  {$_.MESSAGE -Match 'Sleep Reason: Application API'}{Type='Sleep matched using Message';break} {$_.ID -eq '42'}{'Type=Sleep matched using EventID';break} }}},MESSAGE|ConvertTo-Csv -NoTypeInformation | %{ $_ -replace """`r`n""",',' } | select -Skip 1 | Out-File -Append c:\logs\timeline\TEMP_TimeLine.csv"

消息字段显然具有字符串'睡眠原因:应用程序API'正如我们从第一个输出中看到的那样。想知道这里发生了什么......有什么线索的专家呢?

1 个答案:

答案 0 :(得分:0)

好的,我看到两个问题:

A)你可能打破了自己的剧本。我会在一秒钟内完成 B)你在$ _。消息行上错过了'Type='Sleep应为'Type=Sleep

好的,回到A点。我将从;break开始。在99%的情况下没有这样做,你会让脚本之神生气,而你生气的时候就不会喜欢它们。在大多数情况下,您希望使用;Continue。 Break完全打破了事物,并且根据它的使用位置,它可以突破父循环,完全停止在一系列事物中。另一方面继续移动到当前循环的末尾,跳过其他任何东西。一样?有点,排序,但是继续不会像Break那样打破ForEach-Object循环。

所以,说到这里,让我们在你的开关中尝试这个:

Switch ($_)  { 
    {$_.ID -eq '42'}{'Type=Sleep matched using EventID';continue} 
    {$_.MESSAGE -Match 'Sleep Reason: Application API'}{'Type=Sleep matched using Message';continue}
}

好的,这很好,连同点B中的整个'问题可能会修复代码。

所以,说到这就是为什么你这样运行呢?亲爱的领主,经营一个疯狂的长衬垫是疯了。将它保存到.PS1文件,如果你是从批处理文件中调用它然后调用脚本文件,但是ug,这一般很难处理,难怪你错过了'中间那条线。如果从批处理文件中调用它,请将其命名为GetSleepLo​​gs.ps1(或任何您想要的,只需在命令中修改文件名)并尝试:

PowerShell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -File GetSleepLogs.ps1

编辑:我不喜欢convertto-CSV |选择-skip 1 | %{%_ -replace ...} | Out-File的事情,对我来说似乎很笨拙。此外,Select命令上的所有即兴哈希表都有点难以理解。查看这个创建1个具有多个属性的对象的替代方法,然后将其设置为Export-CSV,并设置-append和-NoTypeInformation开关,这些开关应该只是将其固定到现有CSV文件的底部。

Get-WinEvent -EA SilentlyContinue -FilterHashtable @{Logname='System';ID=42}| ForEach{[PSCustomObject][Ordered]@{
    'TimeCreated' = Get-Date $_.TimeCreated -Format 'yyyy-MM-dd HH:mm:ss'
    'DayOfWeek' = (Get-Date $_.TimeCreated).DayOfWeek
    'ID' = $_.ID
    'ID Description' = Switch($_){
                        {$_.ID -eq '42' -AND $_.Message -match 'Sleep Reason: Application API'}{'Type=Sleep matched using EventID and Message';continue}
                        {$_.ID -eq '42'}{'Type=Sleep matched using EventID';continue}
                        {$_.Message -match 'Sleep Reason: Application API'}{'Type=Sleep matched using Message';continue}}
    'MESSAGE' = $_.Message.replace("`r`n`r`n","`r`n") -replace "((?<!`")`r`n|`n|`r)", ","
}}|Export-Csv C:\temp\TimeLine.csv -NoTypeInformation -append