3

We have a client system there users connect to SAP 9.2 through a server.

When a user runs SAP 9.2 on web, SAP initiates an exe process on the server, just like it would when you run SAP client application. Once the user is done working on SAP, usually the user will not select file and exit but will just close the tab assuming SAP has been closed.

On the server the SAP exe process is not closed, yesterday I noticed the server memory was full (100% utilization) while only one user was logged in. On the task manager, we had over 100 SAP exe processes running. I had to manually close all services after which the SAP 9.2 on web started running smoothly.

Today am back to 11 or so SAP processes, as per the attached screenshot and only four users have logged in since yesterday evening and no one was logged in when I took the screenshot.

enter image description here

My question is, how can I make use of TASKKILL or any other method to kill all dormant processes that belong to SAP Business One and not affect logged in users?

Users are on Windows Server 2012 standard edition.

Adriano Repetti
  • 60,141
  • 17
  • 127
  • 190
Kinyanjui Kamau
  • 1,825
  • 9
  • 50
  • 86

1 Answers1

2

You didn't tag your question with any specific tag ( or , for example) then I'd assume you want a batch file. Algorithm is the same regardless the language you use but obviously syntax is pretty different (PowerShell script is much easier and short).

From command line (then eventually with a scheduled task or an autostart operation when an user logs-in) you can use TASKKILL:

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

Few notes:

  • Replace imagename.exe with the image name of SAP Business One process (check it using TASKLIST), alternatively you may use WINDOWTITLE filter.
  • If users are logged-in under a domain you may want to replace %USERNAME% with %USERDOMAIN%\%USERNAME%.
  • /F switch forcefully close specified process, do it only if a gentle termination does not work.
  • /T closes the process and all its children (I see some of those processes have children).
  • Check TASKKILL help for more filters, note that this will kill all the processes that not belongs to the user currently logged-in which is executing this command. It has one obvious implication: logged-in user has to have required permissions and you have only one logged-in user at any time.

Implications of last point are somehow huge and things will be more complicate if you need to circumvent that. Given that you can get detailed process information using TASKLIST /Vand you can format the output in a convenient format using (let's assume for this example that process image name is sapbo.exe):

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

Which can be parsed using something like this:

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

You need the to determine if an user is logged-in or not. If it's an interactive session you may just check for Windows Shell process (read it from registry if you want to do things well...) Simplest way I know is to use code from this post:

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

Because you need to kill the process if it has not a logged-in user then put this after DO part (it's one line, here I split just for clarity):

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

Do not forget to adapt this code to your specific case...


As I said with PowerShell it is much easier. First of all you want to get all the processes eligible to be killed:

Get-Process sapbo -IncludeUserName

Loop through them and check if there is the interactive session:

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

Please note that I wrote code here then it's not tested, be careful...

Community
  • 1
  • 1
Adriano Repetti
  • 60,141
  • 17
  • 127
  • 190