Skip to main content

How to Check if IIS is Running in Batch Script

Before performing deployments, running health checks, or executing maintenance tasks on a web server, the first step is to verify that IIS is actually running. Attempting to deploy files, recycle application pools, or modify configurations on a stopped IIS service leads to cryptic errors and failed automation. A quick status check at the beginning of any IIS management script saves time and prevents cascading failures.

In this guide, we will explore multiple methods to check whether IIS is running from a Batch Script, ranging from simple service queries to comprehensive health checks that include HTTP response validation.

Method 1: Checking the W3SVC Service State

The World Wide Web Publishing Service (W3SVC) is the core IIS service. If it is running, IIS is operational.

@echo off
setlocal

echo Checking if IIS is running...

:: Check if the service exists first
sc query W3SVC >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] IIS ^(W3SVC^) is not installed on this machine.
pause
exit /b 1
)

:: Check the service state
sc query W3SVC 2>nul | findstr /i "RUNNING" >nul
if %errorlevel% equ 0 (
echo [OK] IIS ^(W3SVC^) is RUNNING.
pause
exit /b 0
)

sc query W3SVC 2>nul | findstr /i "STOPPED" >nul
if %errorlevel% equ 0 (
echo [WARNING] IIS ^(W3SVC^) is STOPPED.
pause
exit /b 1
)

:: Neither RUNNING nor STOPPED, check for transitional states
sc query W3SVC 2>nul | findstr /i "PENDING" >nul
if %errorlevel% equ 0 (
echo [WARNING] IIS ^(W3SVC^) is in a transitional state ^(START_PENDING or STOP_PENDING^).
) else (
echo [WARNING] IIS ^(W3SVC^) is in an unknown state.
)

pause
exit /b 1

Understanding SC QUERY Output

The sc query command returns the service status in a structured format:

SERVICE_NAME: W3SVC
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
WIN32_EXIT_CODE : 0 (0x0)

The STATE line contains the keyword we check: RUNNING, STOPPED, START_PENDING, or STOP_PENDING.

IIS relies on multiple services. A thorough check examines all of them.

@echo off
setlocal enabledelayedexpansion

echo =============================================
echo IIS SERVICE STATUS
echo =============================================
echo.

set "all_ok=1"

for %%S in (W3SVC WAS) do (
set "state=NOT INSTALLED"

sc query %%S >nul 2>&1
if !errorlevel! equ 0 (
sc query %%S 2>nul | findstr /i "RUNNING" >nul
if !errorlevel! equ 0 (
set "state=RUNNING"
) else (
set "state=NOT RUNNING"
set "all_ok=0"
)
) else (
set "all_ok=0"
)

echo %%S: !state!
)

echo.
if "!all_ok!"=="1" (
echo [RESULT] IIS is fully operational.
) else (
echo [RESULT] IIS is NOT fully operational.
)

pause

Method 3: Using IISRESET /STATUS

The iisreset tool has a built-in status check:

@echo off
setlocal

:: Check if iisreset is available
where iisreset >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] iisreset command not found.
echo IIS Management Tools may not be installed.
echo Use "sc query W3SVC" as an alternative.
pause
exit /b 1
)

echo Checking IIS status via iisreset...
echo.

iisreset /status

echo.
if %errorlevel% equ 0 (
echo [OK] IIS status retrieved successfully.
) else (
echo [ERROR] Could not retrieve IIS status.
)

pause

Sample Output

Status for World Wide Web Publishing Service ( W3SVC ) : Running
Status for Windows Process Activation Service ( WAS ) : Running
info

iisreset is only available when the IIS Management Tools feature is installed. On Windows Server Core or minimal IIS installations, this tool may be absent even though the W3SVC service is running. In those cases, use Method 1 or Method 2 which rely on sc query, available on all Windows installations.

Method 4: HTTP Health Check (True Verification)

The most reliable way to confirm IIS is working is to make an actual HTTP request and verify a response comes back. A service can be in RUNNING state but fail to serve requests due to binding conflicts, certificate errors, or application pool crashes.

@echo off
setlocal enabledelayedexpansion

set "url=http://localhost"

echo Performing HTTP health check on %url%...

set "status="
for /f "delims=" %%S in ('powershell -NoProfile -Command ^
"try { $r = Invoke-WebRequest -Uri '%url%' -TimeoutSec 5 -UseBasicParsing; $r.StatusCode } catch { 'UNREACHABLE' }" 2^>nul') do set "status=%%S"

if not defined status set "status=UNREACHABLE"

if "!status!"=="200" (
echo [OK] IIS responded with HTTP 200 at %url%.
) else if "!status!"=="UNREACHABLE" (
echo [ERROR] No HTTP response from %url%.
echo IIS may be stopped, the default site may not be configured,
echo or nothing is bound to port 80 on localhost.
) else (
echo [WARNING] IIS responded with HTTP !status! at %url%.
echo The server is reachable but returned a non-200 status.
)

pause
tip

An HTTP health check against http://localhost only verifies the default site on port 80. If your sites use different ports, hostnames, or HTTPS, adjust the URL accordingly. For HTTPS checks, you may need to add -SkipCertificateCheck (PowerShell 7+) or handle certificate validation errors in the catch block.

Method 5: Comprehensive IIS Health Dashboard

A production-ready script that checks services, sites, and HTTP connectivity:

@echo off
title IIS Health Monitor
setlocal enabledelayedexpansion

set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"

:dashboard
cls
echo =============================================
echo IIS HEALTH DASHBOARD
echo %COMPUTERNAME% - %date% %time:~0,8%
echo =============================================
echo.

:: 1. Service Status
echo [SERVICES]
set "iis_running=0"
for %%S in (W3SVC WAS) do (
set "svc_state=Not Installed"
sc query %%S >nul 2>&1
if !errorlevel! equ 0 (
sc query %%S 2>nul | findstr /i "RUNNING" >nul
if !errorlevel! equ 0 (
set "svc_state=Running"
if "%%S"=="W3SVC" set "iis_running=1"
) else (
set "svc_state=Stopped"
)
)
echo %%S: !svc_state!
)

echo.

:: 2. Website Status (only if IIS is running and appcmd is available)
echo [WEBSITES]
if !iis_running! equ 1 (
if exist "%appcmd%" (
set "sites_up=0"
set "sites_down=0"
set "sites_total=0"

for /f "delims=" %%N in ('"%appcmd%" list site /text:name 2^>nul') do (
set /a "sites_total+=1"
set "site_state=Unknown"
for /f "delims=" %%S in ('"%appcmd%" list site /name:"%%N" /text:state 2^>nul') do set "site_state=%%S"

if /i "!site_state!"=="Started" (
echo [*] %%N
set /a "sites_up+=1"
) else (
echo [ ] %%N ^(!site_state!^)
set /a "sites_down+=1"
)
)

if !sites_total! equ 0 (
echo [No websites configured]
) else (
echo.
echo Running: !sites_up! Stopped: !sites_down! Total: !sites_total!
)
) else (
echo appcmd.exe not found. Cannot query sites.
)
) else (
echo Cannot query, W3SVC is not running.
)

echo.

:: 3. HTTP Response Check
echo [HTTP CHECK]
set "http_status="
for /f "delims=" %%S in ('powershell -NoProfile -Command ^
"try { $r = Invoke-WebRequest -Uri 'http://localhost' -TimeoutSec 3 -UseBasicParsing; $r.StatusCode } catch { 'UNREACHABLE' }" 2^>nul') do set "http_status=%%S"

if not defined http_status set "http_status=UNREACHABLE"

if "!http_status!"=="200" (
echo http://localhost - 200 OK
) else (
echo http://localhost - !http_status!
)

echo.
echo =============================================
echo Press any key to refresh, or Ctrl+C to exit.
pause >nul
goto :dashboard

Using the Check in Deployment Scripts

The most practical application is a pre-flight check before deployment:

@echo off
setlocal

echo [PRE-FLIGHT] Checking IIS...

:: Verify IIS is installed
sc query W3SVC >nul 2>&1
if %errorlevel% neq 0 (
echo [ABORT] IIS ^(W3SVC^) is not installed.
pause
exit /b 1
)

:: Verify IIS is running
sc query W3SVC 2>nul | findstr /i "RUNNING" >nul
if %errorlevel% neq 0 (
echo [ABORT] IIS is not running. Cannot deploy.
echo Start IIS with: iisreset /start or net start W3SVC
pause
exit /b 1
)

echo [OK] IIS is running. Proceeding with deployment...

:: ... deployment steps follow ...

Common Mistakes

The Wrong Way: Checking with NET START (Listing All Services)

:: WRONG - net start lists ALL running services, slow and hard to parse
net start | findstr /i "World Wide Web"
danger

The net start command outputs every running service on the machine, which can be dozens or hundreds of lines. It is slow, and the display name "World Wide Web Publishing Service" is localized on non-English systems (e.g., it becomes a completely different string in German or Japanese). Use sc query W3SVC which targets the specific service by its invariant internal name.

The Wrong Way: Assuming IIS is Running

:: WRONG - No check before operations
"%appcmd%" recycle apppool /apppool.name:"DefaultAppPool"

If IIS is stopped, this command fails with an error that does not clearly indicate the root cause. Always verify IIS is running before performing management operations.

The Wrong Way: Checking Only the Service Without Testing HTTP

:: INCOMPLETE - Service may be running but sites may not respond
sc query W3SVC | findstr /i "RUNNING" >nul
if %errorlevel% equ 0 echo IIS is healthy!
warning

A RUNNING service state confirms the W3SVC process is active, but it does not guarantee that websites are actually serving requests. The default site may be stopped, port 80 may be blocked by another application, SSL certificates may be misconfigured, or application pools may have crashed. For true health verification, supplement the service check with an HTTP request (Method 4).

Best Practices

  1. Use sc query W3SVC: It is fast, language-independent, and returns machine-parseable status.
  2. Check both W3SVC and WAS: Both services must be running for IIS to function properly.
  3. Add HTTP health checks: Service status alone does not guarantee the website is serving pages. An actual HTTP request confirms end-to-end functionality.
  4. Use as a pre-flight check: Begin every deployment or maintenance script with an IIS status verification.
  5. Distinguish between "not installed" and "not running": Use sc query W3SVC >nul 2>&1 to check if the service exists before checking its state. This provides clearer error messages and avoids confusing a missing service with a stopped one.
  6. Handle transitional states: Services can be in START_PENDING or STOP_PENDING states. Your scripts should handle these instead of treating any non-RUNNING state as "stopped."
  7. Check for appcmd.exe and iisreset availability: These tools may not be present on minimal installations. Always provide fallback paths using sc query.

Conclusion

Checking if IIS is running from a Batch Script is most reliably accomplished by querying the W3SVC service state with sc query. For comprehensive verification, checking both W3SVC and WAS services, followed by an HTTP health check against localhost, provides full confidence that the web server is operational. Integrating these checks into deployment and maintenance scripts as pre-flight validations prevents failed operations and provides clear diagnostic feedback when IIS is unexpectedly down.