Skip to content

Instantly share code, notes, and snippets.

@juntalis
Created March 18, 2018 02:17
Show Gist options
  • Save juntalis/35e8c5be7ead13588dcc6531918625de to your computer and use it in GitHub Desktop.
Save juntalis/35e8c5be7ead13588dcc6531918625de to your computer and use it in GitHub Desktop.
Windows batch script to start/stop/restart/toggle VMWare Workstation related services.
@echo off
setlocal
goto main
:safeset
rem Set a variable only if it's not already set
if defined %~1 goto :EOF
call set "%~1=%%~2"
goto :EOF
:service_status
rem Query the status of a service
set _SERVICE_STATUS=
for /F "tokens=4 skip=3" %%S in ('%SystemRoot%\system32\sc.exe query "%~2"') do @call :safeset _SERVICE_STATUS "%%~S"
call set "%~1=%%_SERVICE_STATUS%%"
set _SERVICE_STATUS=
goto :EOF
:apply_action
rem Apply an action to all services
set VMWD_ERROR=
set VMWD_ERRORLEVEL=
set VMWD_ACTION_ORDER=
if /i "%~2x"=="stopx" set VMWD_ACTION_ORDER=stop
if /i "%~2x"=="startx" set VMWD_ACTION_ORDER=start
if defined VMWD_ACTION_ORDER goto apply_action_%VMWD_ACTION_ORDER%_order
:apply_action_start_order
call :%~1 VMAuthdService
call :%~1 VMnetDHCP
call :%~1 "VMware NAT Service"
call :%~1 VMUSBArbService
call :%~1 VMwareHostd
goto apply_action_end
:apply_action_stop_order
call :%~1 VMwareHostd
call :%~1 VMnetDHCP
call :%~1 "VMware NAT Service"
call :%~1 VMUSBArbService
call :%~1 VMAuthdService
:apply_action_end
if defined VMWD_ERROR echo "%VMWD_ERROR%"
if defined VMWD_ERRORLEVEL exit /B %VMWD_ERRORLEVEL%
goto :EOF
:action_toggle
rem Increments VMWD_STATUS_COUNT if the status of the specified service is "RUNNING"
set VMWD_STATUS=
call :service_status VMWD_STATUS "%~1"
if /i "%VMWD_STATUS%"=="RUNNING" set /A VMWD_STATUS_COUNT+=1
goto :EOF
:action_start
rem Action to be applied to each service to start them.
if defined VMWD_ERRORLEVEL goto :EOF
call :if_status STOPPED start "%~1"
goto :EOF
:action_stop
rem Action to be applied to each service to stop them.
if defined VMWD_ERRORLEVEL goto :EOF
call :if_status RUNNING stop "%~1"
goto :EOF
:if_status
rem Conditionally applies an action to a service if it meets the status requirements.
set VMWD_STATUS=
call :service_status VMWD_STATUS "%~3"
set "VMWD_CMD_OUTPUT=%TEMP%\vmwd_%RANDOM%.log"
if not "%VMWD_STATUS%x"=="%~1x" echo %~3 status "%VMWD_STATUS%" != "%~1". Skipping..
if /i "%VMWD_STATUS%x"=="%~1x" echo %~3: Applying action "%~2"..
if /i "%VMWD_STATUS%x"=="%~1x" call "%SystemRoot%\system32\sc.exe" %~2 "%~3" >"%VMWD_CMD_OUTPUT%" 2>&1
if errorlevel 1 set VMWD_ERRORLEVEL=%ERRORLEVEL%
if defined VMWD_ERRORLEVEL set /p VMWD_ERROR=<"%VMWD_CMD_OUTPUT%"
if exist "%VMWD_CMD_OUTPUT%" call del /F /Q "%VMWD_CMD_OUTPUT%">nul 2>nul
goto :EOF
:cmd_usage
rem Usage text.
echo Usage: %VMWD_COMMAND% [start^|stop^|restart^|toggle]
goto :EOF
:cmd_toggle
rem Determine which branch of logic we should go down based on the number of
rem services currently in the 'running' state.
set /A VMWD_STATUS_COUNT=0
call :apply_action action_toggle
echo Determining toggle action..
echo Detected %VMWD_STATUS_COUNT% running services..
if %VMWD_STATUS_COUNT% GEQ 3 goto cmd_stop
goto cmd_start
:cmd_start
rem Entrypoint of the "start" action.
echo Starting VMWare services..
call :apply_action action_start start
goto :EOF
:cmd_stop
rem Entrypoint of the "stop" action.
echo Stopping VMWare services..
call :apply_action action_stop stop
goto :EOF
:cmd_restart
rem Entrypoint of the "stop" action.
echo Restarting VMWare services..
call :cmd_stop
call :cmd_start
goto :EOF
:main
rem Entrypoint
set "VMWD_COMMAND=%~0"
rem Command line option resolution
set "VMWD_ARG=%~1"
if /i "%VMWD_ARG%x"=="stopx" goto cmd_stop
if /i "%VMWD_ARG%x"=="startx" goto cmd_start
if /i "%VMWD_ARG%x"=="togglex" goto cmd_toggle
if /i "%VMWD_ARG%x"=="restartx" goto cmd_restart
if /i "%VMWD_ARG:~1%x"=="?x" goto cmd_usage
if /i "%VMWD_ARG:~1%x"=="hx" goto cmd_usage
if /i "%VMWD_ARG:~2%x"=="helpx" goto cmd_usage
if "%VMWD_ARG%x"=="x" goto cmd_toggle
goto getopt_error
:getopt_error
rem Error handler for bad argument.
echo ERROR: Unrecognized command line argument: "%~1"
echo.
call :cmd_usage
exit /B 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment