I am trying to parse the output of WMIC and then to get the PID.
My script is as following:
@echo off
setLocal enableExtensions enableDelayedExpansion
FOR /F "tokens=1* delims=" %%A IN ('"wmic process where(name="java.exe") get ProcessID,commandline| FINDSTR /v "CommandLine" | FINDSTR "TestServer""') DO (
set "line=%%A"
@REM echo "%%A"
for /F "tokens=* delims= " %%C in ("%%A") do (
echo "%%C"
echo "%%D"
)
)
The output is as follows:
"java com.test.TestServer 7560 "
"%D"
"java com.test.TestServer 7380 "
"%D"
My target here is to grab the Process ID.
I have tried with space as the delims in the FOR loop. Yet no luck.
So my question is how to format the columns of the WMIC and to get the columns?
WMIC uses a subset of SQL syntax. You can functionally put the FINDSTR tests in the WMIC WHERE clause by using the LIKE operator with %
as the wildcard. Since it is in a batch script, the %
needs to be doubled.
It is much easier to parse out the ProcessID since the CommandLine value is no longer needed in the WMIC output. I added the SessionID to put an unused value at the end to make it easier to parse the value without worrying about the unwanted carriage return character that FOR /F somehow introduces when it converts the WMIC unicode output into ANSI.
@echo off
setlocal
set "pid="
for /f "skip=1" %%A in (
'wmic process where "name='java.exe' and commandline like '%%TestServer%%' and not commandline like '%%CommandLine%%'" get processid^, sessionid'
) do if not defined pid set "pid=%%A"
EDIT in response to question in comment
The FOR /F conversion of WMIC unicode also introduces unwanted lines that look to be empty but actually contain a single carriage return. In my code above I assume you expect a single line, so I use an IF DEFINED to effectively ignore the unwanted trailing "blank" line.
Another approach is needed if you expect multiple values. An extra FOR /F loop will remove the unwanted carriage returns, so the lines truly become empty and are therefore ignored. Based on your comment, it looks like you no longer need to ignore command lines that contain "CommandLine".
I don't know what you need to do with the values, so the code below simply echoes each value. I use SKIP=1 in place of piping the result through FINDSTR to avoid the header line.
@echo off
for /f "skip=1" %%A in (
'wmic process where "name='java.exe' and commandline like '%%TestServer%%'" get processid'
) do for /f %%B in ("%%A") do echo %%B
The delims parameter will be ignored when using tokens=*
As you need the third token, you should use token=3
This worked on my system to get the PID of the single running process.
@echo off
FOR /F %%A IN ('"wmic process where name="java.exe" get ProcessID,commandline |findstr [0-9] " ') DO echo "%%A"
pause
for /f "tokens=1*delims==" %%a in ('wmic process where 'name^="java.exe" AND CommandLine like "%%TestServer%%"' get ProcessID /format:list^|find /i "ProcessID"') do set "ProcessID=%%b"
echo %ProcessID%