When automating IIS configuration through PowerShell, understanding binding structures is crucial. The WebAdministration
module provides the necessary cmdlets to manage bindings, but the syntax requires precise parameter formatting.
For multiple bindings, we need to construct a proper binding collection object rather than a simple hashtable:
$bindings = @(
@{
protocol="http";
bindingInformation=($ip + ":80:" + $hostRecord)
},
@{
protocol="https";
bindingInformation=($ip + ":443:" + $hostRecord);
sslFlags=1 # Required for HTTPS
}
)
Here's the enhanced version with certificate handling for HTTPS:
Param(
[Parameter(Mandatory=$True)]
[string]$hostname,
[Parameter(Mandatory=$True)]
[string]$installPath,
[string]$ip="*",
[string]$certThumbprint
)
Import-Module WebAdministration
# App pool creation
$appPoolName = $hostname + 'Pool'
New-WebAppPool -Name $appPoolName
Set-ItemProperty "IIS:\AppPools\$appPoolName" -Name managedRuntimeVersion -Value "v4.0"
# Binding configuration
$hostRecord = $hostname + '.example.com'
$bindings = @(
@{protocol="http";bindingInformation="$($ip):80:$hostRecord"},
@{protocol="https";bindingInformation="$($ip):443:$hostRecord";certificateStoreName="MY";certificateHash=$certThumbprint}
)
# Site creation
New-WebSite -Name $hostname -Port 80 -IPAddress $ip -HostHeader $hostRecord
-PhysicalPath $installPath -ApplicationPool $appPoolName
# Adding HTTPS binding separately for better control
if($certThumbprint) {
New-WebBinding -Name $hostname -Protocol "https" -Port 443 -IPAddress $ip
-HostHeader $hostRecord -SslFlags 1
$binding = Get-WebBinding -Name $hostname -Protocol "https"
$binding.AddSslCertificate($certThumbprint, "MY")
}
After running the script, verify the bindings with:
Get-WebBinding -Name "$hostname" | Format-Table -Property protocol,bindingInformation
Common issues to check:
- Certificate thumbprint validity
- Binding conflicts
- Port availability
- App pool permissions
To modify bindings on an existing site:
# Remove existing binding
Remove-WebBinding -Name $hostname -Protocol "http" -HostHeader $oldHostRecord
# Add new binding
New-WebBinding -Name $hostname -Protocol "https" -Port 443 -IPAddress $ip
-HostHeader $newHostRecord -SslFlags 1
When managing IIS sites programmatically, the WebAdministration
module provides powerful cmdlets for binding manipulation. The key challenge lies in properly structuring binding information and handling both HTTP and HTTPS protocols simultaneously.
Here's an improved script that handles multiple bindings with proper parameter validation:
#Requires -RunAsAdministrator
Param(
[Parameter(Mandatory=$true)]
[string]$SiteName,
[Parameter(Mandatory=$true)]
[string]$PhysicalPath,
[Parameter(Mandatory=$false)]
[string]$IPAddress = "*",
[Parameter(Mandatory=$true)]
[string]$HostHeader,
[Parameter(Mandatory=$false)]
[string]$CertificateThumbprint
)
Import-Module WebAdministration
# Create application pool
$appPool = $SiteName + "AppPool"
New-WebAppPool -Name $appPool -Force
Set-ItemProperty "IIS:\AppPools\$appPool" -Name "managedRuntimeVersion" -Value "v4.0"
# Create bindings collection
$bindings = @(
@{
protocol = "http"
bindingInformation = "$($IPAddress):80:$($HostHeader)"
}
)
# Add HTTPS binding if certificate specified
if ($CertificateThumbprint) {
$bindings += @{
protocol = "https"
bindingInformation = "$($IPAddress):443:$($HostHeader)"
certificateThumbprint = $CertificateThumbprint
certificateStoreName = "My"
}
}
# Create site with all bindings
New-Website -Name $SiteName -PhysicalPath $PhysicalPath -ApplicationPool $appPool -Force -Binding $bindings
For more complex requirements, consider these additional techniques:
# Adding bindings to existing site
Get-WebBinding -Name "ExistingSite" | Remove-WebBinding
New-WebBinding -Name "ExistingSite" -Protocol "http" -Port 8080 -IPAddress "*" -HostHeader "alternate.example.com"
# SNI binding (requires IIS 8+)
New-WebBinding -Name $SiteName -Protocol "https" -Port 443 -IPAddress "*" -HostHeader $HostHeader -SslFlags 1
Always validate inputs and handle common IIS deployment errors:
try {
if (-not (Test-Path $PhysicalPath)) {
throw "Physical path does not exist"
}
if ($CertificateThumbprint -and -not (Get-ChildItem Cert:\LocalMachine\My\$CertificateThumbprint)) {
throw "Certificate not found in local machine store"
}
# Implementation here...
}
catch {
Write-Error "IIS Deployment Failed: $_"
exit 1
}
After deployment, verify all bindings are correctly configured:
Get-Website -Name $SiteName | Select-Object -ExpandProperty Bindings
Get-WebBinding -Name $SiteName | Format-Table -Property protocol,bindingInformation