How to Get the Path to a Service's Executable in Batch Script
For security audits, diagnostic checks, or deployment verification, you often need to find the exact location of the executable file that a Windows service is running. This "path to executable" tells you if a service is running from the correct location (e.g., C:\Windows\System32) or from a potentially insecure or incorrect one. The standard, built-in command-line tool for querying the detailed configuration of a service is SC.EXE (Service Control).
This guide will teach you how to use the sc qc command to query a service's configuration and how to parse its output to extract the BINARY_PATH_NAME. This is the definitive method for finding the executable path for any service on the system.
The Core Command: SC QC (Query Configuration)
The sc.exe utility is the primary tool for service management. The qc (Query Configuration) sub-command displays the static configuration of a service, which includes its executable path, dependencies, and startup type.
Syntax: SC QC <ServiceName>
QC: The sub-command to Query Configuration.<ServiceName>: The short, internal name of the service (e.g.,Spooler), not its long Display Name.
An Alternative Method: Using WMIC
The WMIC utility provides a more direct way to get this specific piece of information, and its output is often cleaner.
Syntax: WMIC SERVICE WHERE Name="<ServiceName>" GET PathName
SERVICE: The WMI alias forWin32_Service.WHERE Name="...": A filter to select the service by its short name.GET PathName: The specific property that holds the executable path.
Basic Example: Displaying a Service's Configuration
Let's query the configuration for the Print Spooler service, whose short name is Spooler.
@ECHO OFF
ECHO --- Querying Configuration for 'Spooler' service ---
ECHO.
SC QC Spooler
The output is a detailed list of properties. The one we care about is BINARY_PATH_NAME.
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: Spooler
TYPE : 110 WIN32_OWN_PROCESS (interactive)
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\System32\spoolsv.exe
LOAD_ORDER_GROUP : SpoolerGroup
TAG : 0
DISPLAY_NAME : Print Spooler
DEPENDENCIES : RPCSS
: http
SERVICE_START_NAME : LocalSystem
How to Capture the Path in a Variable
To use the path in a script, you must parse the output of the command. Because the output of sc qc is so verbose, we should pipe it to findstr to isolate the line we need before parsing it with a FOR /F loop.
Script Using SC QC (Recommended)
@ECHO OFF
SET "ServiceName=Spooler"
SET "ServicePath="
ECHO --- Capturing Executable Path for '%ServiceName%' ---
REM 'tokens=2,*' splits by the first colon. %%B gets everything after it.
FOR /F "tokens=1,* delims=:" %%A IN (
'SC QC "%ServiceName%" ^| findstr "BINARY_PATH_NAME"'
) DO (
SET "ServicePath=%%B"
)
REM The result has a leading space, so we trim it.
FOR /F "tokens=*" %%P IN ("%ServicePath%") DO SET "ServicePath=%%P"
ECHO.
ECHO The executable path is: "%ServicePath%"
Script Using WMIC (Simpler Parsing)
@ECHO OFF
SET "ServiceName=Spooler"
SET "ServicePath="
FOR /F "skip=1 delims=" %%P IN (
'WMIC SERVICE WHERE Name^="%ServiceName%" GET PathName'
) DO (
SET "ServicePath=%%P" & GOTO :PathFound
)
:PathFound
ECHO WMIC Method Result: "%ServicePath%"
How the Command Works
Both commands interface with the Service Control Manager (SCM), the core Windows service that manages all other services. They query the configuration stored for the service in the registry, specifically the ImagePath value located at: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<ServiceName>
SC QCsimply formats and displays the contents of this and other related registry values.
Common Pitfalls and How to Solve Them
Problem: Using the Wrong Service Name
You must use the internal Service Name (e.g., wuauserv), not the friendly Display Name (e.g., "Windows Update").
Solution: If you only know the Display Name, you can find the Service Name with the SC GETKEYNAME command.
C:\> SC GETKEYNAME "Print Spooler"
[SC] GetServiceKeyName SUCCESS
Name = Spooler
Problem: Parsing the Output is Clumsy
The output of SC QC has a specific format (KEY : VALUE). If you don't parse it correctly, you can get the wrong information or extra unwanted characters.
Solution: The two-step process is the most robust:
- Isolate the line: Pipe the output of
SC QCtofindstr "BINARY_PATH_NAME"to get only the line you care about. - Parse the line: Use
FOR /F "tokens=1,* delims=:"to split the key from the value, and then use a secondFOR /Floop to trim the leading space from the result. TheWMICmethod avoids this complexity, making it a strong alternative.
Practical Example: A Security Check Script
This script checks a list of services to ensure they are all running from the expected, secure System32 directory. It will flag any service whose path points elsewhere.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "ExpectedPath=C:\Windows\System32"
ECHO --- Service Path Security Audit ---
ECHO Verifying that critical services run from %ExpectedPath%...
ECHO.
FOR %%S IN (
Spooler
Schedule
wuauserv
) DO (
SET "ServicePath="
FOR /F "tokens=1,* delims=:" %%A IN ('SC QC "%%S" ^| findstr "BINARY_PATH_NAME"') DO (
SET "ServicePath=%%B"
)
FOR /F "tokens=*" %%P IN ("!ServicePath!") DO SET "ServicePath=%%P"
REM Get the parent folder of the executable path
FOR %%F IN ("!ServicePath!") DO SET "ParentFolder=%%~dpF"
REM Compare the parent folder (case-insensitive)
IF /I "!ParentFolder:~0,-1!" NEQ "%ExpectedPath%" (
ECHO [WARNING] Service '%%S' is running from an unexpected location:
ECHO !ServicePath!
ECHO.
) ELSE (
ECHO [OK] Service '%%S' is running from the correct location.
)
)
ENDLOCAL
Conclusion
The sc qc command is the standard, built-in tool for querying the detailed configuration of a Windows service, including the path to its executable.
Key takeaways for using it in a script:
- You must provide the correct internal Service Name, not the Display Name.
- Pipe the output to
findstr "BINARY_PATH_NAME"to isolate the correct line. - Use a
FOR /Floop to parse this line and capture the path into a variable. - Remember to trim the leading space from the captured value.
- For a simpler parsing experience,
WMIC SERVICE GET PathNameis an excellent alternative.