Skip to main content

How to Start or Stop a Specific Website in IIS using Batch Script

In a typical IIS installation, a single server hosts multiple websites. When performing maintenance, deploying updates, or troubleshooting a specific application, you rarely want to restart all of IIS. Instead, you need to start or stop an individual website while leaving all other sites running and serving requests undisturbed.

In this guide, we will explore how to target and control specific IIS websites using the appcmd.exe command-line tool within a Batch Script.

Prerequisites

  • IIS must be installed with appcmd.exe available at %SystemRoot%\System32\inetsrv\.
  • Administrator privileges are required.
  • You need to know the exact site name as configured in IIS (visible in IIS Manager or via appcmd list site).

Method 1: Starting a Specific Website

@echo off
setlocal

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

:: Verify Admin
net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Administrator privileges required.
pause
exit /b 1
)

:: Verify appcmd exists
if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found at: %appcmd%
echo IIS may not be installed or Management Tools are missing.
pause
exit /b 1
)

:: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Website "%site_name%" not found in IIS.
echo Run "%appcmd%" list site to see available sites.
pause
exit /b 1
)

:: Check if already running
"%appcmd%" list site /name:"%site_name%" /text:state 2>nul | findstr /i "Started" >nul
if %errorlevel% equ 0 (
echo [INFO] "%site_name%" is already running.
pause
exit /b 0
)

echo Starting website "%site_name%"...

"%appcmd%" start site /site.name:"%site_name%"

if %errorlevel% equ 0 (
echo [SUCCESS] "%site_name%" is now running.
) else (
echo [ERROR] Failed to start "%site_name%".
echo Check that its binding does not conflict with another site.
echo Run "%appcmd%" list site to check bindings.
)

pause

Method 2: Stopping a Specific Website

@echo off
setlocal

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

net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)

if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)

:: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Website "%site_name%" not found in IIS.
pause
exit /b 1
)

:: Check if already stopped
"%appcmd%" list site /name:"%site_name%" /text:state 2>nul | findstr /i "Stopped" >nul
if %errorlevel% equ 0 (
echo [INFO] "%site_name%" is already stopped.
pause
exit /b 0
)

echo Stopping website "%site_name%"...

"%appcmd%" stop site /site.name:"%site_name%"

if %errorlevel% equ 0 (
echo [SUCCESS] "%site_name%" has been stopped.
echo The site will no longer respond to HTTP requests.
) else (
echo [ERROR] Failed to stop "%site_name%".
echo Check the System Event Log for details.
)

pause

Method 3: Checking the Current State of a Website

Before starting or stopping a site, it is good practice to check its current state.

@echo off
setlocal enabledelayedexpansion

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

if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)

echo Checking status of "%site_name%"...
echo.

"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Site "%site_name%" not found in IIS.
echo.
echo Available sites:
"%appcmd%" list site
pause
exit /b 1
)

:: Display the site details
"%appcmd%" list site /name:"%site_name%"

:: Extract and display the state clearly
set "state="
for /f "delims=" %%S in ('"%appcmd%" list site /name:"%site_name%" /text:state 2^>nul') do set "state=%%S"

echo.
if /i "!state!"=="Started" (
echo [STATUS] %site_name% is RUNNING.
) else if /i "!state!"=="Stopped" (
echo [STATUS] %site_name% is STOPPED.
) else (
echo [STATUS] %site_name% state: !state!
)

pause

The output of appcmd list site looks like:

SITE "CompanyBlog" (id:3,bindings:http/*:80:blog.company.com,state:Started)

The state: field shows either Started or Stopped.

Method 4: Interactive Site Manager

For administrators who manage multiple sites, an interactive menu is the most practical tool.

@echo off
title IIS Site Manager
setlocal enabledelayedexpansion

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

net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Run as Administrator.
pause
exit /b 1
)

if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)

:menu
cls
echo =============================================
echo IIS WEBSITE MANAGER
echo =============================================
echo.
echo Current Sites:
echo.

:: List all sites with their states
"%appcmd%" list site
if !errorlevel! neq 0 (
echo [No sites found or IIS service not running]
)

echo.
echo Commands:
echo start [name] - Start a website
echo stop [name] - Stop a website
echo list - Refresh the list
echo exit - Quit
echo.

set "cmd="
set /p "cmd=Enter command: "

if not defined cmd goto :menu

:: Parse command
set "action="
set "target="
for /f "tokens=1,*" %%A in ("!cmd!") do (
set "action=%%A"
set "target=%%B"
)

if /i "!action!"=="exit" exit /b 0
if /i "!action!"=="list" goto :menu

if /i "!action!"=="start" (
if not defined target (
echo [ERROR] Usage: start [site name]
pause
goto :menu
)
"%appcmd%" list site /name:"!target!" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Site "!target!" not found.
) else (
"%appcmd%" start site /site.name:"!target!"
)
pause
goto :menu
)

if /i "!action!"=="stop" (
if not defined target (
echo [ERROR] Usage: stop [site name]
pause
goto :menu
)
"%appcmd%" list site /name:"!target!" >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] Site "!target!" not found.
) else (
"%appcmd%" stop site /site.name:"!target!"
)
pause
goto :menu
)

echo [ERROR] Unknown command: "!action!"
echo Valid commands: start, stop, list, exit
pause
goto :menu

Method 5: Deploy Pattern (Stop, Update, Start)

The most common production use case is stopping a specific site, deploying new files, and starting it again.

@echo off
setlocal enabledelayedexpansion

set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=CustomerPortal"
set "site_path=C:\inetpub\sites\portal"
set "deploy_source=\\BuildServer\Releases\Portal\Latest"

net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)

if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)

echo =============================================
echo DEPLOYING TO: %site_name%
echo =============================================
echo.

:: Step 1: Verify the site exists
"%appcmd%" list site /name:"%site_name%" >nul 2>&1
if !errorlevel! neq 0 (
echo [ABORT] Site "%site_name%" not found in IIS.
pause
exit /b 1
)

:: Step 2: Verify the deploy source is accessible
if not exist "%deploy_source%\" (
echo [ABORT] Deploy source not accessible: %deploy_source%
echo Check network connectivity and share permissions.
pause
exit /b 1
)

:: Step 3: Stop the site
echo [1/4] Stopping %site_name%...
"%appcmd%" stop site /site.name:"%site_name%" >nul 2>&1

:: Step 4: Also stop the app pool to release file locks
set "pool_name="
for /f "delims=" %%P in ('"%appcmd%" list app /site.name:"%site_name%" /text:applicationPool 2^>nul') do set "pool_name=%%P"

if defined pool_name (
echo [2/4] Stopping pool: !pool_name!...
"%appcmd%" stop apppool /apppool.name:"!pool_name!" >nul 2>&1

:: Wait for worker processes to terminate (poll up to 10 seconds)
set "wp_wait=0"
:wp_loop
"%appcmd%" list wp /apppool.name:"!pool_name!" 2>nul | findstr /i "WP" >nul
if !errorlevel! neq 0 goto :wp_done
if !wp_wait! geq 10 (
echo [WARNING] Worker processes did not terminate within 10 seconds.
goto :wp_done
)
set /a "wp_wait+=1"
timeout /t 1 /nobreak >nul
goto :wp_loop
:wp_done
) else (
echo [2/4] No dedicated app pool found.
)

:: Step 5: Deploy files
echo [3/4] Copying new files...
xcopy "%deploy_source%\*" "%site_path%\" /s /e /y /q >nul
set "copy_result=!errorlevel!"
if !copy_result! neq 0 (
echo [WARNING] File copy completed with issues. Exit code: !copy_result!
)

:: Step 6: Start the app pool and site
echo [4/4] Starting %site_name%...
if defined pool_name (
"%appcmd%" start apppool /apppool.name:"!pool_name!" >nul 2>&1
)
"%appcmd%" start site /site.name:"%site_name%"

:: Verify site is running
"%appcmd%" list site /name:"%site_name%" /text:state 2>nul | findstr /i "Started" >nul
if !errorlevel! equ 0 (
echo.
echo [SUCCESS] Deployment complete. %site_name% is back online.
) else (
echo.
echo [ERROR] %site_name% did not reach Started state after deployment.
echo Check the System Event Log and application logs.
pause
exit /b 1
)

pause
tip

Stopping the application pool in addition to the site is important for deployments. Even after the site stops accepting new requests, the worker process (w3wp.exe) may still hold file locks on DLLs and configuration files. Stopping the pool ensures all locks are released before file copy begins.

Controlling Multiple Sites at Once

If you need to stop several related sites simultaneously (e.g., during a server-wide maintenance window):

@echo off
setlocal enabledelayedexpansion

set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "sites=SiteA SiteB SiteC"

net session >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] Admin required.
pause
exit /b 1
)

if not exist "%appcmd%" (
echo [ERROR] appcmd.exe not found. IIS may not be installed.
pause
exit /b 1
)

echo Stopping selected sites...
for %%S in (%sites%) do (
"%appcmd%" list site /name:"%%S" >nul 2>&1
if !errorlevel! equ 0 (
"%appcmd%" stop site /site.name:"%%S" >nul 2>&1
echo [STOPPED] %%S
) else (
echo [SKIP] %%S: Not found.
)
)

echo.
echo Perform maintenance tasks now. Press any key to restart sites.
pause >nul

echo.
echo Starting sites...
for %%S in (%sites%) do (
"%appcmd%" list site /name:"%%S" >nul 2>&1
if !errorlevel! equ 0 (
"%appcmd%" start site /site.name:"%%S" >nul 2>&1
echo [STARTED] %%S
) else (
echo [SKIP] %%S: Not found.
)
)

echo.
echo [DONE] All operations complete.
pause

Common Mistakes

The Wrong Way: Using iisreset for a Single Site

:: WRONG - This restarts ALL IIS sites, not just one
iisreset
danger

iisreset stops and starts the entire IIS server, affecting every website hosted on the machine. If you only need to restart one site, use appcmd stop site followed by appcmd start site to avoid disrupting other production applications.

The Wrong Way: Not Checking Whether the Site Exists

:: WRONG - If the name is misspelled, appcmd produces a cryptic error
"%appcmd%" stop site /site.name:"compnay-blog"
warning

If the site name does not match any site in IIS, appcmd returns a generic error message that does not clearly indicate the name was wrong. Always verify the site exists with appcmd list site /name:"..." before attempting start or stop operations. This catches typos early and provides a clear error message.

The Wrong Way: Deploying Without Stopping the App Pool

:: WRONG - Site is stopped but worker process may still hold file locks
"%appcmd%" stop site /site.name:"MyApp"
xcopy "\\source\*" "C:\inetpub\myapp\" /s /e /y
warning

Stopping a site prevents new HTTP requests from being accepted, but existing worker processes (w3wp.exe) may continue running and hold file locks on DLLs, configuration files, and data files. File copy operations will fail or produce partial results. Always stop the application pool as well, and wait for worker processes to terminate before copying files.

Best Practices

  1. Use appcmd for granular control: It targets individual sites without affecting the rest of the server.
  2. Stop the app pool for deployments: File locks from running worker processes can prevent file overwrites during deployment. Stop the pool and verify workers have terminated before copying.
  3. Verify the site exists first: Always run appcmd list site /name: before attempting start/stop operations to catch typos early and provide clear error messages.
  4. Check the state before acting: Attempting to stop an already-stopped site or start an already-running site returns an error. Check the current state to provide accurate feedback and avoid misleading error messages.
  5. Verify appcmd.exe exists: Check for the tool at the start of every script to provide a clear error message on systems where IIS is not installed.
  6. Verify the site state after operations: After starting a site (especially post-deployment), confirm it reached Started state rather than assuming the start command succeeded.

Conclusion

Starting and stopping specific IIS websites from a Batch Script is efficiently handled by the appcmd start site and appcmd stop site commands. Unlike iisreset, which affects the entire server, appcmd provides surgical control over individual sites, making it the correct tool for targeted deployments, maintenance windows, and troubleshooting sessions. By incorporating state checks, application pool management, and deployment file operations, administrators can build professional, zero-downtime website management workflows.