【问题标题】:Script to kill dormant SAP Processes杀死休眠 SAP 进程的脚本
【发布时间】:2016-09-14 09:19:01
【问题描述】:

我们有一个客户端系统,用户通过服务器连接到 SAP 9.2。

当用户在 Web 上运行 SAP 9.2 时,SAP 会在服务器上启动一个 exe 进程,就像运行 SAP 客户端应用程序时一样。一旦用户在 SAP 上完成工作,通常用户不会选择文件并退出,而只会关闭选项卡(假设 SAP 已关闭)。

在服务器上,SAP exe 进程没有关闭,昨天我注意到服务器内存已满(100% 利用率),而只有一个用户登录。在任务管理器上,我们有超过 100 个 SAP exe 进程在运行。我不得不手动关闭所有服务,之后 SAP 9.2 on web 才开始顺利运行。

今天我回到了 11 个左右的 SAP 进程,根据所附的屏幕截图,自昨天晚上以来只有四个用户登录,当我截取屏幕截图时没有人登录。

我的问题是,如何使用 TASKKILL 或任何其他方法来杀死属于 SAP Business One 的所有休眠进程而不影响已登录的用户?

用户使用的是 Windows Server 2012 标准版。

【问题讨论】:

    标签: powershell batch-file windows-server-2012


    【解决方案1】:

    您没有使用任何特定标签(例如)标记您的问题,那么我假设您需要一个批处理文件。 算法不管你使用什么语言都是一样的,但显然语法是完全不同的(PowerShell脚本更简单更短)。

    从命令行(最终在用户登录时使用计划任务或自动启动操作)您可以使用TASKKILL

    TASKKILL /FI "IMAGENAME eq imagename.exe" /FI "USERNAME ne %USERNAME%" /T /F
    

    几点说明:

    • imagename.exe替换为SAP Business One流程的镜像名称(使用TASKLIST检查),或者您可以使用WINDOWTITLE过滤器。
    • 如果用户在域下登录,您可能希望将 %USERNAME% 替换为 %USERDOMAIN%\%USERNAME%
    • /F switch 强制关闭指定进程,只有在 温和 终止不起作用时才这样做。
    • /T 关闭进程及其所有子进程(我看到其中一些进程有子进程)。
    • 查看TASKKILL 帮助以获取更多过滤器,注意这将杀死所有不属于当前登录的执行此命令的用户的进程。它有一个明显的含义:登录用户必须具有所需的权限,并且您在任何时候都只有一个登录用户。

    最后一点的含义在某种程度上是巨大的,如果您需要规避它,事情会变得更加复杂。假设您可以使用TASKLIST /V获取详细的流程信息,并且您可以使用方便的格式来格式化输出(假设此示例的流程映像名称为sapbo.exe):

    TASKLIST /V /FO:CSV /FI "IMAGENAME eq sapbo.exe"
    

    可以使用这样的方法解析

    FOR /F "delims=, tokens=1-7" %1 IN ('TASKLIST /V /FO:CSV "IMAGENAME eq sapbo.exe"') DO (
        echo %1 %7
    )
    

    您需要确定用户是否已登录。如果它是一个交互式会话,你可以只检查 Windows Shell 进程(如果你想把事情做好,从注册表中读取它......)我知道的最简单的方法是使用来自 this post 的代码:

    TASKLIST /FI "IMAGENAME eq myapp.exe" 2>NUL | FIND /I /N "myapp.exe">NUL
    IF "%ERRORLEVEL%"=="0" ECHO Programm is running
    

    因为如果没有登录用户,您需要终止该进程,然后将其放在DO 部分之后(这是一行,为了清楚起见我在这里分开):

    TASKLIST /FI "IMAGENAME eq winlogon.exe" /FI "USERNAME eq %7" 2>NUL
        | FIND /I /N "winlogon.exe" > NUL
        || TASKKILL /T /F /PID %2
    

    不要忘记根据您的具体情况调整此代码...


    正如我所说的 PowerShell,它要容易得多。首先你要让所有有资格被杀死的进程:

    Get-Process sapbo -IncludeUserName
    

    遍历它们并检查是否存在交互式会话:

    foreach ($eligibleProcess in Get-Process sapbo -IncludeUserName)
    {
        if (-not Get-Process winlogon -ErrorAction SilentlyContinue -IncludeUserName | where { $_.UserName -eq $eligibleProcess.UserName })
        {
            $eligibleProcess.Kill();
        }
    }
    

    请注意,我在这里写了代码然后它没有经过测试,小心......

    【讨论】:

      猜你喜欢
      • 2016-01-24
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 2013-07-24
      • 2016-07-08
      • 1970-01-01
      • 2023-03-26
      • 2013-03-26
      相关资源
      最近更新 更多