Powershell命令不能一致地处理日志

时间:2015-04-20 14:07:26

标签: powershell dos pipeline

我有一些使用

监视putty日志文件的代码
Get-Content $LogPath -tail 0 -wait | Select-String -Pattern $Alarms -SimpleMatch | 
      ForEach-Object { & $PageApp SendSubScriber $PageUser `"$_`"}

我将发布下面的完整脚本,但这是大脑'一个脚本,它将实时监视日志文件的字符串数组($ Alarms),并将完整的字符串传递给命令行分页应用程序($ PageApp)。

如果我运行此脚本并手动将行添加到包含警报字符串的受监视文件中,则每次都会根据需要对其进行分页。即。

Add-Content $LogPath "Low-Battery"

问题在于,当这个设备生成事件时,putty会写入日志文件,但没有任何反应......如果我打开并关闭putty日志,那么我将使用最后一个事件进行分页。我想这与其他程序使用的日志文件有关。但是即使putty会话正在运行,我也可以使用add-content手动注入警报字符串,并且我会正确分页,只有在串行设备写入文件时才会进行分页。

有没有办法调试get-content命令,所以我可以看到为什么它没有将字符串传递给dos命令?当事情正常工作时,我会在控制台窗口看到输出,但是当这个串行设备写入putty日志时,没有任何内容。

这是整个代码:

#Log To Process for Events
$LogFile = "SRAS-$(Get-Date -format dd-MM-yyyy).log"
$LogPath = "C:\SRAS\Logs\$LogFile"

#Output File for Paging
$PageFile = "PAGES-$(Get-Date -format dd-MM-yyyy).log"
$PagePath = "C:\SRAS\Pages\$PageFile"

#Variables for Paging
$PageApp = "C:\Program Files (x86)\ISS\Air Messenger Pro 7\SendCmd.exe"
$PageUser = "Test"

#Strings to monitor for
$Alarms = @("AC/BATT_PWR","OVERTEMP","ILA_DC-FEED","LOW-BATTERY","FO_RF-LINKB","FO_RF-LINKA","FO_DATALINK")

#Check if Needed Files Exist. If Not Create Them.
if (-not (Test-Path $LogPath))
    { New-Item $LogPath -ItemType file -Value "[$(Get-Date)] - New File Created `n"| Out-Null}
Else {
    echo "$LogFile Already Exists - appending to file"
    }
if (-not (Test-Path $PagePath))
    { New-Item $PagePath -ItemType file | Out-Null}
else {
    echo "$PageFile Already Exists - appending to file"
    }

#Variable to check if putty.exe is running
$putty_proc = get-process -name putty -ErrorAction SilentlyContinue

#Start PuTTy if it isn't running
if ($putty_proc -eq $null)
    {
    Write-Host "[$(Get-Date)] Opening Putty Session for Logging"
    &"C:\tools\Software\putty.exe" -load "SRAS - Logging" 
    }
#If Putty is already Running, Kill and restart to generate log file with current date
else
    {
    Write-Host "[$(Get-Date)] Stopping Current Putty Session..."
    Stop-Process $putty_proc
    Write-Host "[$(Get-Date)] Done"
    Write-Host "[$(Get-Date)] Opening Putty Session for Logging"
    &"C:\tools\Software\putty.exe" -load "SRAS - Logging" 
    }

Write-Host "[$(Get-Date)] Starting job for file $LogPath"


Get-Content $LogPath -tail 0 -wait | Select-String -Pattern $Alarms -SimpleMatch | 
      ForEach-Object { & $PageApp SendSubScriber $PageUser `"$_`"}

$ PagePath和$ PageFile变量的原因是因为最初我只是使用out-file将警报放入文本文件中,这样做没有问题。

1 个答案:

答案 0 :(得分:0)

经过几天拔头发后,我终于解决了问题。

最初,当我写这篇文章时,它是在运行Windows 7的开发设置上,并且所有测试都表明它正在运行。直到我将这个脚本移动到它将运行的服务器上我没有问题。服务器正在运行Windows Server 2008 R2。

如问题所述,如果我打开日志文件,我会被分页,我很清楚它与另一个应用程序出现的文件有关,putty缓存其输出,等等...但是当我在日志文件目录中打开Windows资源管理器并点击F5时,我也会收到警报。

我不太了解操作系统真正解释它,但从我可以想象的,当putty写入文件窗口时,看不到文件被更新,反过来也没有是powershell。当我Add-Content手动写入文件时,它的最后修改后的属性会立即更新并且我会获得一个页面,我只能推测这是一个像google那样的Windows问题很多服务器2008的例子没有正确更新文件/目录。

修复

while($true)
{
$now = Get-Date

#Log To Process for Events
$LogFile = "SRAS-$(Get-Date -format dd-MM-yyyy).log"
$LogPath = "C:\SRAS\Logs\$LogFile"

#Output File for Paging
$PageFile = "PAGES-$(Get-Date -format dd-MM-yyyy).log"
$PagePath = "C:\SRAS\Pages\$PageFile"

#Variables for Paging
$PageHeader = "SRAS ALARM:"
$PageApp = "C:\Program Files (x86)\ISS\Air Messenger Pro 7\SendCmd.exe"
$PageUser = "Test"

#Strings to monitor for
$Alarms = @("AC/BATT_PWR","OVERTEMP","ILA_DC-FEED","LOW-BATTERY","FO_RF-LINKB","FO_RF-LINKA","FO_DATALINK")

#Check if Needed Files Exist. If Not Create Them.
if (-not (Test-Path $LogPath))
    { New-Item $LogPath -ItemType file -Value "[$(Get-Date)] - New File Created`n"| Out-Null}
Else {
    echo "$LogFile Already Exists - appending to file"
    }
if (-not (Test-Path $PagePath))
    { New-Item $PagePath -ItemType file | Out-Null}
else {
    echo "$PageFile Already Exists - appending to file"
    }

#Variable to check if putty.exe is running
$putty_proc = get-process -name putty -ErrorAction SilentlyContinue

#Start PuTTy if it isn't running
if ($putty_proc -eq $null)
    {
    Write-Host "[$(Get-Date)] Opening Putty Session for Logging"
    &"C:\Program Files (x86)\PuTTY\putty.exe" -load "SRAS - Logging" 
    }
#If Putty is already Running, Kill and restart to generate log file with current date
else
    {
    Write-Host "[$(Get-Date)] Stopping Current Putty Session..."
    Stop-Process $putty_proc
    Write-Host "[$(Get-Date)] Done"
    Write-Host "[$(Get-Date)] Opening Putty Session for Logging"
    &"C:\Program Files (x86)\PuTTY\putty.exe" -load "SRAS - Logging" 
    }

#Start Backround Job processing Log File
Write-Host "[$(Get-Date)] Starting job for file $LogPath"
$latest = Start-Job -Arg $LogPath, $Alarms, $PagePath, $PageHeader, $PageApp, $PageUser -ScriptBlock {
    param($a_LogPath,$a_Alarms,$a_PagePath, $a_PageHeader, $a_PageApp, $a_PageUser)

    # wait until the file exists, just in case
    while(-not (Test-Path $a_LogPath)){ sleep -sec 10 }

    Get-Content $a_LogPath -tail 0 -wait | Select-String -inputobject {$_.substring(9,27)} -Pattern $a_Alarms -SimpleMatch | foreach {& $a_PageApp SendSubScriber $a_PageUser `"$a_PageHeader $_`"}

   }

# wait until day changes, or whatever would cause new log file to be created
while($now.Date -eq (Get-Date).Date){ 
#This forces a refresh of the log file (server 2008 glitch?)
get-content $LogPath | Out-Null
sleep -Sec 10 }

# kill the job and start over
Write-Host "[$(Get-Date)] Stopping job for file $LogPath"
$latest | Stop-Job
}

解决方案是从底部开始的第六行。在日志文件上使用Get-Content强制刷新。这是while循环的一部分,它寻找每10秒更改一次的日期。对我而言,这似乎并不是最优的,但我对脚本的了解不足以使其更好。

主要部分作为后台作业运行,实时过滤日志文件,并将带有所需字符串的事件发送到分页应用程序。

对'关键'进行了一些细微的修改。我之前发布的代码,但这只是为了我自己的过滤目的。