Redirect pipe to a variable in Windows batch file
To set a variable to the output of a command, use for /f
:
for /f "tokens=*" %%a in ('command') do set _CmdResult=%%a
The problem is, to use a pipe in the command you need to escape it with the command line escape character: ^
, therefore: ^|
.
for /f "tokens=*" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a
Now, I'm not sure which version of Windows you're running, but my attempts at a sc
query on Windows 7 give the following output:
>sc query SamSs
SERVICE_NAME: SamSs
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
This means a findstr STATE
would be required, which gives the output:
>sc query SamSs | findstr STATE
STATE : 4 RUNNING
Now, in the example above, tokens=*
means every token is set to the variable %%a
, where tokens are separated by spaces. In this case, you can use either the third token (4
) or fourth token (RUNNING
). By the way, with testing, 1
corresponds to STOPPED
for me.
To make things easier, I'll be using the string RUNNING
in this example. So we want the fourth token.
for /f "tokens=4" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATE') do set _CmdResult=%%a
Of course, depending on what your sc query
outputs, yours may be slightly different, so follow how I got there and modify as needed. Or post in a comment the output of your sc query
and I'll modify as needed.
To check the value, you can use:
if %_CmdResult%==STOPPED (
REM do something here
)
In your case, the loop would go something like this.
:loop
for /f "tokens=*" %%a in ('sc \\192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a
if %_CmdResult%==STOPPED (
sc \\192.168.1.1 start <ServiceName>
goto endloop
)
timeout /t 5
goto loop
:endloop
Note that timeout
is a utility only included in Windows Vista and later. Windows XP can use something like ping 1.1.1.1 -n 1 -w 5000 > nul
.