Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell命令不一致地处理日志_Powershell_Dos_Pipeline - Fatal编程技术网

Powershell命令不一致地处理日志

Powershell命令不一致地处理日志,powershell,dos,pipeline,Powershell,Dos,Pipeline,我有一段代码,它使用 Get-Content $LogPath -tail 0 -wait | Select-String -Pattern $Alarms -SimpleMatch | ForEach-Object { & $PageApp SendSubScriber $PageUser `"$_`"} 我将在下面发布完整的脚本,但这是一个脚本的“大脑”,它将实时监视日志文件中的字符串数组$报警,并将完整的字符串传递给命令行分页应用程序$PageApp 如果我运行此脚

我有一段代码,它使用

Get-Content $LogPath -tail 0 -wait | Select-String -Pattern $Alarms -SimpleMatch | 
      ForEach-Object { & $PageApp SendSubScriber $PageUser `"$_`"}
我将在下面发布完整的脚本,但这是一个脚本的“大脑”,它将实时监视日志文件中的字符串数组$报警,并将完整的字符串传递给命令行分页应用程序$PageApp

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

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文件将警报放在文本文件中,该文件工作正常。

经过几天的努力,我终于解决了问题

最初我写这篇文章时,它是在一个运行Windows7的开发设置上运行的,所有的测试都表明它工作正常。直到我将这个脚本移动到它将运行的服务器上,我才发现这个问题。服务器正在运行Windows server 2008 R2

正如问题中提到的,如果我打开日志文件,我会被分页,我确信这与另一个应用程序使用的文件、putty缓存其输出等有关。。。但是,当我在日志文件目录中打开windows资源管理器并点击F5时,我也收到了警报

我对操作系统的了解还不足以真正解释它,但从我的理解来看,当putty写入文件时,windows并没有看到文件正在更新,而powershell也没有。当我添加内容手动写入文件时,它的上次修改属性会立即更新,我会得到一个页面,我只能推测这是windows的问题,因为谷歌有很多Server2008没有正确更新文件/目录的例子

修复

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内容强制刷新。这是while循环的一部分,它每10秒查找一次要更改的日期。对我来说,这似乎不是最优的,但我对脚本编写的了解还不够,无法使它变得更好

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


我之前发布的“关键”代码有一些轻微的修改,但这只是出于我自己的过滤目的。

我今天刚刚注意到,只有当串行设备生成的事件是阵列AC/BATT_PWR中的第一项时,这才起作用。刚刚测试了您这里的关键代码,它对我起作用。我唯一的想法是,操作系统没有将数据刷新到磁盘上,而get content在刷新之前不会看到数据。我曾经在一家生产文件复制软件的公司工作,这是我们在IIS日志中遇到的问题。操作系统在有64K的写操作之前不会刷新对日志文件的写操作。但是,由于更改在缓存中,所以在使用记事本打开文件时会显示更改,因为这些更改尚未刷新到磁盘。没有解释你最后的评论,但这是我对可能发生的事情的唯一想法。我感觉问题在于在管道中使用foreach对象。最初,我试图使用Get Content$LogPath-tail 0-wait | Select String-Pattern$Alarms-SimpleMatch |和$PageApp sendsubscriber$pageuser$|但是$|周围的引号无法传递。dos应用程序需要在发送到分页终端的文本周围加上双引号,但我似乎只能使用foreach object命令中的脚本块来获得传递。使用像我之前提到的out文件这样的替代文件,可以根据需要工作。关于让报价在$左右传递有什么提示吗?