You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:53:23