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
| Component | Values | Description |
|---|---|---|
| Protocol | http, https | The transfer protocol |
| IP Address | *, 192.168.1.100, etc. | Which network interface to listen on. * = all interfaces |
| Port | 80, 443, 8080, etc. | The TCP port number |
| Host Header | www.example.com, `` (empty) | The domain name filter. Empty = catch all on this port |
Examples
| Binding | Meaning |
|---|---|
http/*:80: | HTTP on all IPs, port 80, no host filter |
http/*:80:www.example.com | HTTP 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.local | HTTP 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"
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
- Always use
/+bindings.to add: Never overwrite the binding collection unless you explicitly intend to replace everything. - 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.
- Verify after changes: Run
appcmd list site /name:"SiteName"after every binding modification to confirm the result. - 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.