Skip to main content

How to Set IIS Website Bindings (Port, Hostname) from Batch Script

Website bindings define how IIS listens for incoming HTTP and HTTPS requests. Each binding specifies a protocol, IP address, port number, and optional hostname (Host Header). Properly configuring bindings is essential for hosting multiple websites on a single server, enabling HTTPS, and routing traffic to the correct application based on the requested domain name.

In this guide, we will explore how to add, modify, and remove IIS website bindings from a Batch Script using the appcmd.exe command-line tool.

Understanding the Binding Format

An IIS binding string follows this format:

protocol/IPAddress:Port:HostHeader

ComponentValuesDescription
Protocolhttp, httpsThe transfer protocol
IP Address*, 192.168.1.100, etc.Which network interface to listen on. * = all interfaces
Port80, 443, 8080, etc.The TCP port number
Host Headerwww.example.com, `` (empty)The domain name filter. Empty = catch all on this port

Examples

BindingMeaning
http/*:80:HTTP on all IPs, port 80, no host filter
http/*:80:www.example.comHTTP on all IPs, port 80, only for www.example.com
https/*:443:HTTPS on all IPs, port 443, no host filter
http/*:8080:HTTP on all IPs, non-standard port 8080
http/192.168.1.10:80:intranet.localHTTP on a specific IP, port 80, for intranet.local

Method 1: Adding a Binding to an Existing Website

To add a new binding (for example, adding a second hostname) to a site that already exists:

@echo off
setlocal

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

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

echo Adding binding to "%site_name%"...

:: Add a second hostname binding
"%appcmd%" set site /site.name:"%site_name%" /+bindings.[protocol='http',bindingInformation='*:80:www.example.com']

if %errorlevel% equ 0 (
echo [SUCCESS] Binding added: http *:80:www.example.com
) else (
echo [ERROR] Failed to add binding. It may already exist.
)

:: Show current bindings
echo.
echo Current bindings for %site_name%:
"%appcmd%" list site /name:"%site_name%"

pause
endlocal

The + Prefix

The + before bindings. tells appcmd to add a new binding to the existing list rather than replacing all bindings. Without the +, you would overwrite the entire binding collection.

Method 2: Removing a Binding

To remove a specific binding from a site:

@echo off
setlocal

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

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

echo Removing binding from "%site_name%"...

:: Remove the specific binding (note the - prefix)
"%appcmd%" set site /site.name:"%site_name%" /-bindings.[protocol='http',bindingInformation='*:80:old.example.com']

if %errorlevel% equ 0 (
echo [SUCCESS] Binding removed.
) else (
echo [ERROR] Binding not found or removal failed.
)

:: Show current bindings
echo.
echo Current bindings for %site_name%:
"%appcmd%" list site /name:"%site_name%"

pause
endlocal

The - prefix before bindings. tells appcmd to remove the matching binding from the collection.

Method 3: Changing the Port of a Website

To change the port a website listens on (e.g., from 80 to 8080), you remove the old binding and add the new one.

@echo off
setlocal

set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=DevSite"
set "old_port=80"
set "new_port=8080"
set "hostname=dev.local"

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

echo Changing %site_name% from port %old_port% to %new_port%...

:: Remove the old binding
echo Removing old binding (*:%old_port%:%hostname%^)...
"%appcmd%" set site /site.name:"%site_name%" /-bindings.[protocol='http',bindingInformation='*:%old_port%:%hostname%']

if %errorlevel% neq 0 (
echo [WARNING] Old binding not found or already removed.
)

:: Add the new binding
echo Adding new binding (*:%new_port%:%hostname%^)...
"%appcmd%" set site /site.name:"%site_name%" /+bindings.[protocol='http',bindingInformation='*:%new_port%:%hostname%']

if %errorlevel% equ 0 (
echo [SUCCESS] Port changed from %old_port% to %new_port%.
) else (
echo [ERROR] Failed to add new binding.
)

:: Verify
echo.
echo Current bindings:
"%appcmd%" list site /name:"%site_name%"

pause
endlocal

Method 4: Adding an HTTPS Binding with SSL Certificate

HTTPS bindings require both a binding entry and an SSL certificate assignment. The certificate is referenced by its thumbprint.

@echo off
setlocal

set "appcmd=%SystemRoot%\System32\inetsrv\appcmd.exe"
set "site_name=SecureSite"
set "hostname=secure.example.com"

:: Replace with your actual certificate thumbprint (no spaces)
set "cert_hash=A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2"

:: Replace with a unique GUID for your application
set "app_id={00112233-4455-6677-8899-AABBCCDDEEFF}"

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

echo Adding HTTPS binding to "%site_name%"...

:: 1. Add the HTTPS binding
"%appcmd%" set site /site.name:"%site_name%" /+bindings.[protocol='https',bindingInformation='*:443:%hostname%']

if %errorlevel% neq 0 (
echo [ERROR] Failed to add HTTPS binding.
pause
exit /b 1
)

echo HTTPS binding added.

:: 2. Assign the SSL certificate using netsh
echo Assigning SSL certificate...
netsh http add sslcert hostnameport=%hostname%:443 certhash=%cert_hash% certstorename=My appid=%app_id%

if %errorlevel% equ 0 (
echo [SUCCESS] HTTPS binding with SSL certificate configured.
echo Site accessible at: https://%hostname%
) else (
echo [ERROR] SSL certificate assignment failed. Verify the certificate thumbprint.
echo.
echo Tip: List available certificates with:
echo powershell -Command "Get-ChildItem Cert:\LocalMachine\My"
)

pause
endlocal

Finding Your Certificate Thumbprint

:: List all certificates in the Local Machine Personal store
powershell -NoProfile -Command ^
"Get-ChildItem Cert:\LocalMachine\My | Format-Table Subject, Thumbprint, NotAfter -AutoSize"
warning

The appid in the netsh command is an arbitrary GUID that identifies your application. You can generate one or use any unique GUID. It does not need to match any existing application registration.

Method 5: Bulk Binding Configuration

For provisioning multiple bindings at once (e.g., adding HTTP bindings for several hostnames):

@echo off
setlocal enabledelayedexpansion

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

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

echo Adding multiple bindings to "%site_name%"...
echo.

set "added=0"
set "failed=0"

:: Define hostnames to bind
set "hosts=www.example.com example.com shop.example.com blog.example.com"

for %%H in (%hosts%) do (
echo Adding: http *:80:%%H
"%appcmd%" set site /site.name:"%site_name%" /+bindings.[protocol='http',bindingInformation='*:80:%%H'] >nul 2>&1

if !errorlevel! equ 0 (
echo [OK]
set /a "added+=1"
) else (
echo [SKIP] Already exists or failed.
set /a "failed+=1"
)
)

echo.
echo Added !added! binding(s^), skipped !failed!.
echo.
echo Final bindings:
"%appcmd%" list site /name:"%site_name%"

pause
endlocal

Common Mistakes

The Wrong Way: Overwriting All Bindings

:: WRONG - This replaces ALL existing bindings with just one
"%appcmd%" set site /site.name:"MySite" /bindings:http/*:8080:

Output Concern: Without the + prefix, the /bindings: parameter replaces the entire binding collection. If the site previously had bindings for port 80, HTTPS on 443, and multiple hostnames, they are all lost. Always use /+bindings. to add and /-bindings. to remove individual entries.

The Wrong Way: Duplicate Bindings

:: PROBLEMATIC - Two sites cannot share the same exact binding
"%appcmd%" set site /site.name:"SiteA" /+bindings.[protocol='http',bindingInformation='*:80:']
"%appcmd%" set site /site.name:"SiteB" /+bindings.[protocol='http',bindingInformation='*:80:']

If both sites bind to *:80: with no host header, only one can start. The other will fail with a "Cannot create a file when that file already exists" error. Use different host headers or ports to differentiate.

Best Practices

  1. Always use /+bindings. to add: Never overwrite the binding collection unless you explicitly intend to replace everything.
  2. Use host headers for multi-site servers: Host headers allow multiple sites to share port 80 and 443 by routing based on the requested domain name.
  3. Verify after changes: Run appcmd list site /name:"SiteName" after every binding modification to confirm the result.
  4. Use SNI for multi-domain HTTPS: Server Name Indication (SNI) allows multiple HTTPS sites to share the same IP and port with different certificates based on the hostname.

Conclusion

Setting IIS website bindings from a Batch Script is managed through the appcmd set site command with the /+bindings. (add) and /-bindings. (remove) prefixes. By precisely specifying the protocol, IP address, port, and host header in the bindingInformation parameter, administrators can configure sophisticated multi-domain hosting scenarios, migrate sites between ports, and provision HTTPS with SSL certificate assignments. The key principle is always adding or removing individual bindings rather than overwriting the entire collection.