Batch file to restart a specific service based on

2019-09-17 10:55发布

I'm hoping you can help me with this, I've tried researching for hours but can't seem to get anywhere with it.

I have a process which randomly starts to consume 50+ CPU a few times a day, I'm trying to create a batch file which will run in the background and restart the service if the CPU usage of the process gets above 50 (fixes the issue).

I found something very close on this forum, a guy named "Elektro Hacker" answered, but his answer is the overall CPU usage, not just the usage of a specific process. Here is the batch file he suggested:

@Echo OFF

SET    "SERVICE=Themes"
SET /A "MAXUSAGE=95"
SET /A "INTERVAL=5"

:LOOP 
For /F %%P in ('wmic cpu get loadpercentage ^| FINDSTR "[0-9]"') do (
    IF %%P GTR %MAXUSAGE% (
        Echo [%TIME:~0,8%] CPU Usage: %%P%% Reached the limit: %MAXUSAGE%%%
        Echo Restarting %SERVICE% ...
         SC STOP  "%SERVICE%" 1>NUL
        SC START "%SERVICE%" 1>NUL
        Echo Service restarted.
    ) ELSE (
         Echo [%TIME:~0,8%] CPU Usage: %%P%%
    )
)
Ping -n %INTERVAL% Localhost >NUL
GOTO :LOOP

He also put: "For more precission maybe you want to check the current CPU percentage of the executable associated to the service using:

wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessor
Time

This is the part I can't get past, I keep getting errors, and every time I try to fix it by changing it slightly, I get different errors!

Can anybody change this code slightly, to get it to get the CPU of say "MyProcess" The process and service names are different, I'm not sure if this would make a difference but thought it was worth mentioning.

My coding knowledge is minimal at best, so any help or advice you could give me is greatly appreciated, this is driving my crazy!

Thanks a lot!

3条回答
等我变得足够好
2楼-- · 2019-09-17 11:31

Powesshell can do better

get-process wmiprvse | select processname,cpu,id | ? {$_.cpu -gt 90 -and $_.id} | foreach { restart-service winmgmt }
查看更多
劳资没心,怎么记你
3楼-- · 2019-09-17 11:40

Remove the space:

wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime

You could also do:

wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime | find "myprocess"
查看更多
狗以群分
4楼-- · 2019-09-17 11:48

You need to use ^ to escape the comma from Name,PercentProcessorTime. It should look like:

For /F %%P in ('wmic path Win32_PerfFormattedData_PerfProc_Process get Name^,PercentProcessorTime ^| FINDSTR "[0-9]"') do (

But this is just correct in terms of syntax - findstr will match "ProcessName %Load", whereas the script wants to match only "%Load".
Unfortunately, I'm not proficient in Windows batch scripts and am neither looking for that, so I had to use a third party software called GAWK (gnu awk) to be able to output only the "%Load" part.

This is the script I am using:
NB1: SERVICE=ProcessName - without .exe!
NB2: I'm appending .exe with: "%SERVICE%".exe
NB3: I'm using taskkill instead of sc stop/start

@Echo OFF

SET    "SERVICE=ProcessName"
SET /A "MAXUSAGE=95"
SET /A "INTERVAL=10"

:LOOP 
For /F %%P in ('wmic path Win32_PerfFormattedData_PerfProc_Process get Name^,PercentProcessorTime ^| find "%SERVICE%" ^| "C:\Program Files\GnuWin32\bin\awk.exe" "{print $2}"') do (
    IF %%P GTR %MAXUSAGE% (
        Echo [%TIME:~0,8%] CPU Usage: %%P%% Reached the limit: %MAXUSAGE%%%
        Echo Restarting %SERVICE% ...
         taskkill /f /im "%SERVICE%".exe 1>NUL
        Echo Service restarted.
    ) ELSE (
         Echo [%TIME:~0,8%] CPU Usage: %%P%%
    )
)
Ping -n %INTERVAL% Localhost >NUL
GOTO :LOOP
查看更多
登录 后发表回答