How to List All Disabled Services in Batch Script
Auditing disabled services is a critical task for system troubleshooting and security verification. Sometimes, a service is disabled by a system administrator to save resources, but other times, critical services (like Windows Update or Antivirus) might be disabled by malware to leave the system vulnerable. Knowing how to quickly generate a list of every service currently in a "Disabled" state is essential for maintaining the health and security of a Windows machine.
This guide will explain how to use wmic and sc commands to filter and list all disabled services on your system using a Batch script.
Method 1: Using WMIC (Quick Query)
The wmic (Windows Management Instrumentation Command-line) utility can filter "StartMode" directly in a single query.
Basic Implementation
@echo off
echo [AUDIT] Listing all DISABLED Windows Services...
echo ------------------------------------------------
wmic service where "StartMode='Disabled'" get Name, DisplayName
if %errorlevel% neq 0 (
echo.
echo [ERROR] Failed to query services.
)
echo.
pause
Why this works:
StartMode='Disabled': This strictly filters the Windows database for only those services that are explicitly barred from starting.Name: Returns the internal system name (e.g.,wuauserv).DisplayName: Returns the user-friendly name (e.g.,Windows Update).
Method 2: The SC Loop Method
On some modern versions of Windows, wmic is becoming deprecated. In these environments, you can use the sc command inside a FOR loop to audit the configuration of every service.
@echo off
setlocal enabledelayedexpansion
echo [SCAN] Scanning for disabled services...
echo.
set "Count=0"
:: Loop through the 'SERVICE_NAME' of every registered service
for /f "tokens=2" %%a in ('sc query state^= all ^| findstr /c:"SERVICE_NAME"') do (
:: Check the config for each service
sc qc "%%a" 2>nul | findstr /c:"DISABLED" >nul
if !errorlevel! equ 0 (
echo [DISABLED] %%a
set /a Count+=1
)
)
echo.
echo [DONE] Found !Count! disabled service(s^).
pause
endlocal
The sc query state= all command is necessary because the default sc query command only shows active (running) services, whereas disabled services are always inactive.
Method 3: Exporting to a Log File with Security Alerts
When performing a system audit, it is useful to save the list and flag any critical services that should not be disabled.
@echo off
setlocal enabledelayedexpansion
set "outfile=%~dp0%COMPUTERNAME%_DisabledServices.txt"
set "AlertFound=0"
set "CriticalServices=WinDefend wuauserv MpsSvc BITS CryptSvc"
echo [AUDIT] Generating disabled services report for %COMPUTERNAME%...
:: Write report header
(
echo Disabled Services Report
echo Computer: %COMPUTERNAME%
echo Date: %date% %time%
echo ================================================
) > "%outfile%"
:: Get disabled services and write to report
for /f "skip=1 tokens=1,* delims=" %%a in ('wmic service where "StartMode='Disabled'" get Name /format:table 2^>nul') do (
set "svcname=%%a"
call :ProcessService
)
:: Summary section
(
echo ================================================
echo SUMMARY:
) >> "%outfile%"
if "!AlertFound!"=="1" (
echo [WARNING] CRITICAL security services found DISABLED! >> "%outfile%"
echo Review and re-enable critical services. >> "%outfile%"
) else (
echo [OK] No critical security services found disabled. >> "%outfile%"
)
echo [DONE] Report saved to: %outfile%
if "!AlertFound!"=="1" (
echo.
echo [WARNING] ^! CRITICAL security services are DISABLED on this machine ^!
echo Review: %outfile%
echo.
echo To re-enable a service: sc config "ServiceName" start= demand
echo Then: sc start "ServiceName"
)
pause
endlocal
goto :eof
:ProcessService
:: Trim and validate service name
for /f "tokens=* delims=" %%t in ("!svcname!") do set "svcname=%%t"
:: Remove all spaces (workaround for WMIC quirks)
set "svcname=!svcname: =!"
:: Only process if non-empty AND not the header
if defined svcname if not "!svcname!"=="" if not "!svcname!"=="Name" (
echo [!svcname!] >> "%outfile%"
:: Check for critical services
for %%s in (%CriticalServices%) do (
if /i "!svcname!"=="%%s" (
echo ^[CRITICAL^] This service should NOT be disabled! >> "%outfile%"
echo [ALERT] !svcname! ^(%%s^) is DISABLED - Security Risk!
set "AlertFound=1"
)
)
)
goto :eof
How to Avoid Common Errors
Wrong Way: Using "sc query" without flags
If you just run sc query | findstr "DISABLED", you will likely get zero results.
Why it fails: Standard sc query only scans the "Current State" of running services. Since a disabled service can never be running, it won't appear in the standard list. You must use sc query state= all or wmic.
Problem: WMIC Formatting in Loops
The output of wmic often contains hidden carriage returns (\r\r\n) which can break string comparisons in Batch.
Best Practice: If you need to process the names (e.g., for re-enabling them), pass each value through a for /f loop to strip hidden characters (as shown in Method 3).
Best Practices and Security Rules
1. Identify "Suspicious" Disabled Services
In a standard Windows environment, certain services should almost always be set to "Auto" or "Manual," never "Disabled." If your script finds these in the list, it's a red flag:
WinDefend(Windows Defender Antivirus)wuauserv(Windows Update)MpsSvc(Windows Firewall)
2. Administrator Privileges
While querying service lists is generally allowed, to see all third-party security-protected services, you must run your Batch script as an Administrator.
3. Verification
If you find a service that should be enabled, you can fix it using:
sc config "ServiceName" start= demand
Conclusions
Listing disabled services via Batch script is a critical part of the Windows administrator's toolkit. By leveraging the specific filtering capabilities of wmic or the thorough scanning of sc qc, you can gain full visibility into the components of your system that are currently prohibited from running. This transparency allows you to optimize system performance and proactively identify potential security threats or configuration errors.