PowerShell监控HCSCOM进程脚本查询报错问题排查
问题
我写了一段PowerShell脚本,用来监控酒店系统里负责预订导入的HCSCOM程序(这个程序每两天会挂起一次)。脚本原本应该每3分钟检查一次进程状态:没运行就重启;无响应则先停止再重启。但当HCSCOM进程处于“未响应”状态时,脚本执行报错,错误信息显示查询语句里的ProcessId包含多个数值(比如6512 13196),导致查询无效。
原脚本
$ProcessName = "HCSCOM" While($True) { $Process = Get-Process $ProcessName -ErrorAction SilentlyContinue if ($Process -eq $Null) { Write-Output "The process $ProcessName is not running. Restarting now..." # If the process is a service # Start-Service -Name $ProcessName # If the process is an executable, uncomment the following line and replace with the correct path Start-Process -FilePath "D:\HOTELSYS\HCSCOM\HCSCOM.exe" } else { # Check if the process is not responding $WmiObject = Get-WmiObject -Query "Select * From Win32_Process Where ProcessId = $($Process.Id)" if ($WmiObject.Status -eq "Not Responding") { Write-Output "The process $ProcessName is not responding. Restarting now..." # Stop the process Stop-Process -Name $ProcessName -Force # Start the process again # If the process is a service # Start-Service -Name $ProcessName # If the process is an executable, uncomment the following line and replace with the correct path Start-Process -FilePath "D:\HOTELSYS\HCSCOM\HCSCOM.exe" } else { Write-Output "The process $ProcessName is running." } } Start-Sleep -Seconds 180 # checks every 180 seconds }
错误信息
Get-WmiObject : Invalid query "Select * From Win32_Process Where ProcessId=6512 13196 " At C:\Users\PC\Desktop\scripthcscom.ps1:16 char:22 Get-WmiObject : Invalid query "Select * From Win32_Process Where ProcessId=6512 13196 " At C:\Users\PC\Desktop\scripthcscom.ps1:16 char:22 + ... WmiObject = Get-WmiObject -Query "Select * From Win32_Process Where P ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
解决方案
问题根源
当系统中存在多个同名的HCSCOM进程时,Get-Process $ProcessName会返回一个进程数组,而非单个进程对象。此时$Process.Id会输出所有进程的ID,直接拼到WQL查询语句里就变成了ProcessId=6512 13196,这不符合WQL的语法规则,导致查询报错。
修复后的脚本
$ProcessName = "HCSCOM" $ProcessPath = "D:\HOTELSYS\HCSCOM\HCSCOM.exe" while ($true) { $processes = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue if (-not $processes) { Write-Output "$ProcessName 未运行,正在重启..." Start-Process -FilePath $ProcessPath } else { # 遍历所有同名进程,逐个检查状态 foreach ($proc in $processes) { # 用Get-CimInstance替代已弃用的Get-WmiObject $cimProc = Get-CimInstance -ClassName Win32_Process -Filter "ProcessId = $($proc.Id)" if ($cimProc.Status -eq "Not Responding") { Write-Output "$ProcessName (PID: $($proc.Id)) 未响应,正在重启..." Stop-Process -Id $proc.Id -Force # 等待进程停止后再启动(可选,避免启动冲突) Start-Sleep -Seconds 2 Start-Process -FilePath $ProcessPath } else { Write-Output "$ProcessName (PID: $($proc.Id)) 运行正常" } } } Start-Sleep -Seconds 180 }
关键修改点
- 处理多进程场景:用
foreach循环遍历所有同名进程,避免数组导致的ID拼接错误 - 替换弃用命令:用
Get-CimInstance替代Get-WmiObject(微软已标记WmiObject为弃用,CimInstance是更现代的替代方案) - 精准控制进程:通过PID停止单个无响应进程,而非直接停止所有同名进程(避免误杀正常进程)
- 代码优化:提取进程路径为变量,便于后续维护;增加PID输出,方便定位具体问题进程
内容的提问来源于stack exchange,提问作者Stefan Troplev
相关产品推荐
相关产品推荐

