【问题标题】:Powershell Get-EventLog hangs on RemoteComputerPowershell Get-EventLog 在 RemoteComputer 上挂起
【发布时间】:2014-04-06 05:17:01
【问题描述】:

以下在本地计算机上运行良好,但是当我输入 -ComputerName "myRemoteName" 时,它挂起并且即使在大约 5 分钟后也不返回任何内容;但程序似乎仍在运行。

它是否试图通过“线路”返回一个大数据包? 理论上,我在过去 2 小时内远程计算机上的错误应该少于 10 个。

$getEventLog = Get-EventLog -log application -ComputerName "myRemoteName" -after ((get-date).addMinutes($minutes*-1)) -EntryType Error 
Write-Host Get-Eventlog completed 

# list of events to exclude (based on text found in the message)
$getEventLogFiltered = $getEventLog | Where-Object {$_.Message -notlike 'Monitis*' -and $_.Message -notlike '*MQQueueDepthMonitor.exe*' -and $_.Message -notlike '*The local computer may not have the necessary registry*' }
#to only select certain columns, use Select-Object -Property and list the property/columns                                     
$getEventLogColumns =   $getEventLogFiltered    | Select-Object -Property TimeGenerated,Source,Message,EntryType,MachineName,EventID
$tableFragment = $getEventLogColumns | ConvertTo-Html -fragment
Write-Host "HTML-Table Built"

之后的代码构建一封电子邮件并发送它......

我看过其他建议切换到 Get-WinEvents 的帖子,但我认为这需要我一两个小时来重写(由于我缺乏使用 Powershell 的经验);我上面的内容在本地计算机上运行良好。

Updates 03/04/2014 13:40 CT: 
   Running with $minutes = 120 ran 14.5 minutes. 
   Running with $minutes = 1   ran 12.5 minutes. 

结论,改变 $minutes 的范围似乎并没有真正影响响应时间;两者都很慢。

【问题讨论】:

  • 尝试一些应该运行得更快的方法,例如Get-EventLog -logname application -computername myRemoteName -newest 10。如果这种情况很快恢复,那么您的原始命令可能会发现比您想象的更多的错误。如果没有,那么可能是一些配置问题。 IIRC 此命令使用 DCOM 进行连接。
  • 我用你的 -newest 参数替换了我的 -after 参数(我放了 -newest 2),它很快就回来并发送了电子邮件。最后两个错误发生在午夜左右。这是我的 Prod 系统,我可以登录到 App Event viewer 并验证应用程序事件日志中的错误数量。我已经在 QA 环境中运行这个脚本几个月了(但没有 -ComputerName 参数)。我们在 Prod 中有旧版本的 Powershell,所以我想远程运行。嗯……那现在呢?
  • 它最终还是返回了原始代码,但我在其他机器上没有看它,所以不知道花了多长时间。我现在正在重新运行 Get-EventLog 之前和之后的时间打印。 -after 过滤器是否在远程计算机上运行?
  • 因此没有任何连接/配置问题妨碍您。您的 $minutes 变量设置为什么?也许你会比你想象的更远地回到历史?
  • 尝试 Get-WinEvent 看看是否运行得更快Get-WinEvent -cn myRemoteName -FilterHashtable @{LogName='Application'; Level=2; StartTime=(Get-Date).AddMinutes($minutes * -1)}

标签: powershell get-eventlog


【解决方案1】:

After 参数设计得不是很好,它会打印它应该打印的所有记录,但是当它到达设定的日期时,它仍然会扫描到甚至日志文件的末尾,尽管事实上什么都没有打印(至少看起来如此)。我使用了 Where-object 过滤器和 .CompareTo() 方法来打印设置日期之后的日志(在我的情况下是当前日期的前一天)。

#Sets yesterday date (script will get all records after that date)

$YDate = (Get-Date).AddDays(-1)

#Gets all event logs from Security log where event id represents successful logon and records where generated after prepared date (current date - 24 hours)

$YestardayLogons = Get-EventLog -ComputerName $ServerName -LogName Security | 
    WHERE { ($_.EventId -eq '528') -and ($_.TimeGenerated.CompareTo($YDate) -eq '1') }

【讨论】:

  • 谢谢,听起来很有道理。我无法验证,因为我现在在不同的客户处。
  • 如果我理解正确,那么 WHERE 命令将通过管道传送到 Get-EventLog 命令。这意味着,WHERE 命令将对 Get-EventLog 命令的结果起作用。这再次意味着 Get-EventLog 命令仍然会扫描所有事件,因此与 -After 命令相比,性能不会有任何改进。
【解决方案2】:

似乎我错了,即使使用 Where-Object 过滤器,它仍然会像使用 -after 参数一样进行扫描(我只是在不同的、新构建的机器上进行测试,这就是它完成得如此之快的原因)。

然而,其他研究表明 break 函数可能很有用,所以我所做的是:

Get-EventLog -ComputerName $ServerName -LogName Security | WHERE { ($_.EventID -eq '528')} | ForEach-Object {
  $_
  if ($_.TimeGenerated.CompareTo($YDate) -lt 1) { Break}
}

它会打印所有事件日志,当它遇到早于(在我的情况下为 24 小时)的事件日志时,会启动并停止 get-eventlog cmdlet。
这不是最漂亮的解决方案,但到目前为止它似乎运行良好。

【讨论】:

  • 标记为答案,即使我没有测试过。
  • 对此再提一条评论 - 就像 break 在单个服务器的情况下工作正常,当我在循环中使用它来扫描多个服务器时,中断不仅终止 cmdlet 但整个脚本。为了避免这种情况,我使用了 try{} catch{} 并在我的 if 指令内部而不是 break 我通过 [int ]$Error = "错误" 赋值。由于 try{} catch{} 机制,这会导致 cmdlet 终止。其他选项可能更漂亮的是使用 Trow 指令(也结合 try{}catch{} 机制)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2017-03-12
  • 1970-01-01
相关资源
最近更新 更多