如何使用“Get-wmiObject”监视Windows Java进程

3
我有一些Java组件,有时候会出现崩溃的情况,但唯一的发现方式是当用户抱怨他们收到错误信息时。为此,在我们的监控系统上,我采用了计算服务器上运行的Java进程数量的方法。如果一个组件崩溃了,我会得到警报,因为Java阈值低于正常水平,并登录以找出哪个Java组件崩溃了。这种方法非常有效,但我认为它可以被改进,实现远程启动Java进程并精确定位崩溃的组件。
因此,我考虑编写 Powershell 脚本,从监控系统中执行。我认为我已经完成了“单行代码”,但我需要更多帮助才能完成整个脚本,尽管我认为这个脚本不需要太复杂。
目前我拥有的代码如下:
$theProcess = Get-WmiObject win32_process -Filter "name like '%java%'" | select commandLine

这个命令的输出会给出发送到JVM的所有参数,包括组件的名称。我们称这个组件为“COMP_Number1”,通常有5个Java组件进程正在运行,因此组件的名称为“COMP_Number2”、“COMP_Number3”等。
我的问题是:给定 $theProcess 的输出,如何检查所有Java进程以验证所有组件是否正在运行?如果没有,哪一个没有在运行?
非常感谢!
TT
3个回答

1
你可以像这样做:
$components = @("COMP_Number1","COMP_Number2")
$theProcess | %{ 
    $p = $_
    $running = $components | ?{$p.commandline -match $_}
    $notrunning = $components | ?{ $running -notcontains $_ }
}

$notrunning

谢谢Manojlds。我尝试了所有的答案,你的很好用。但是,在这个块中,我必须使用if then break语句。例如:if ($running -ne $null) {break} - TimmyT

1
如果您可以在服务器上使用WMI,则可以使用WMI事件来检测已停止的进程。
Register-WMIEvent -Query "SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName like 'notepad%'" -Action {Write-Host "kind of notepad process is died"; Write-Host $args}

这里你将检测到 notepad.exenotepad++.exe 的关闭事件。

你可以使用 Get-EventSubscriber 命令来检索你订阅的事件,以及使用 Unregister-Event 命令来取消订阅。

脚本块被视为作业,因此请小心导入你所需的所有模块。

脚本块接收两个参数:

1) System.Management.ManagementEventWatcher

2) System.Management.EventArrivedEventArgs

下面是 $args[1].newevent 的参数:

ExitStatus          Property   System.UInt32 ExitStatus {get;set;}
ParentProcessID     Property   System.UInt32 ParentProcessID {get;set;}
ProcessID           Property   System.UInt32 ProcessID {get;set;}
ProcessName         Property   System.String ProcessName {get;set;}
SECURITY_DESCRIPTOR Property   System.Byte[] SECURITY_DESCRIPTOR {get;set;}
SessionID           Property   System.UInt32 SessionID {get;set;}
Sid                 Property   System.Byte[] Sid {get;set;}

例子:

Register-WMIEvent -Query "SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName like 'notepad%'" -Action {Write-Host "$($args[1].newevent.ProcessName) process is died"}

0
$components = @("COMP_Number1","COMP_Number2")
$running = @()
do {
   Get-WmiObject win32_process -Filter "name like '%java%'" | select commandLine | Foreach-Object {
      $running += ($_.commandLine -replace ".*(COMP_Number\d).*",'$1')
   }
   if ($running.Count -lt $components.Count) {
     Compare-Object ($running | Sort-Object) ($components | Sort-Object)
   }
   $running = @()
   Start-Sleep 50000
} until (1 -lt 0)

正则表达式肯定需要改进。你可以添加一些其他的警告方法(例如电子邮件?)或者尝试在if语句中自动重新启动缺失的进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接