Separate IIS site per domain
The clearest model when domains need separate pools, roots, logs and runtime settings.
Adding a domain in IIS requires creating the site, physical path, application pool and host-header binding together. The PowerShell script creates an isolated pool, directory, www binding and CSV result for each domain.
Import-Module WebAdministration
New-WebAppPool -Name "eka-ornek.com"
New-Website -Name "eka-ornek.com" -Port 80 -IPAddress "*" -HostHeader "ornek.com" -PhysicalPath "C:\inetpub\siteler\ornek.com" -ApplicationPool "eka-ornek.com"
New-WebBinding -Name "eka-ornek.com" -Protocol http -Port 80 -HostHeader "www.ornek.com"
Bulk automation should not accelerate a wrong architecture. Decide customer isolation, resource limits, application roots, mail and DNS ownership first.
The clearest model when domains need separate pools, roots, logs and runtime settings.
For alias domains serving the same application, adding host-header bindings to one site uses fewer resources.
Low-traffic sites in the same trust boundary can share a pool; separate identities and pools are recommended for different customers.
For many HTTPS sites on one IP, define hostname and SNI bindings before certificate automation.
Confirm that the Web-Server role, management tools and PowerShell cmdlets are installed.
Get-WindowsFeature Web-Server,Web-Mgmt-Tools
Get-Module -ListAvailable WebAdministration,IISAdministration Detect duplicate site names, host headers or port conflicts before the operation.
Import-Module WebAdministration
Get-Website
Get-WebBinding Verify NTFS permissions, application-pool startup and binding matching.
Get-Content C:\Eka\domainler.txt -TotalCount 2 | Set-Content C:\Eka\domainler-test.txt In production, sign the script or use process scope instead of permanently setting ExecutionPolicy to Bypass.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass Site, pool, folder and binding creation results are stored in CSV.
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Eka\iis-toplu-domain.ps1 Test with Get-Website, Get-WebBinding and a local Host-header request.
Get-Website | Select Name,State,PhysicalPath
Invoke-WebRequest -Uri http://127.0.0.1 -Headers @{Host="ornek.com"} -UseBasicParsing Creates a site, app pool, directory, www binding, NTFS permission and CSV record for every domain.
$ErrorEylemi = "Stop"
$DomainDosyasi = "C:\Eka\domainler.txt"
$WebKoku = "C:\inetpub\siteler"
$SonucDosyasi = "C:\Eka\iis-domain-sonuclari.csv"
$ErrorDosyasi = "C:\Eka\iis-domain-errorlari.log"
$ErrorActionPreference = $ErrorEylemi
Import-Module WebAdministration
New-Item -ItemType Directory -Path (Split-Path $SonucDosyasi) -Force | Out-Null
New-Item -ItemType Directory -Path $WebKoku -Force | Out-Null
"domain,durum,site,uygulama_havuzu,fiziksel_yol" | Set-Content -Path $SonucDosyasi -Encoding UTF8
"" | Set-Content -Path $ErrorDosyasi -Encoding UTF8
Get-Content $DomainDosyasi | ForEach-Object {
$Domain = $_.Trim().ToLowerInvariant()
$Domain = $Domain -replace '^https?://','' -replace '^www\.','' -replace '/.*$',''
if ([string]::IsNullOrWhiteSpace($Domain)) {
return
}
if ($Domain -notmatch '^[a-z0-9][a-z0-9.-]*\.[a-z]{2,63}$') {
"$Domain,gecersiz,,," | Add-Content -Path $SonucDosyasi -Encoding UTF8
return
}
$SiteAdi = "eka-$Domain"
$HavuzAdi = "eka-$Domain"
$FizikselYol = Join-Path $WebKoku $Domain
try {
New-Item -ItemType Directory -Path $FizikselYol -Force | Out-Null
"<!doctype html><html lang=`"tr`"><meta charset=`"utf-8`"><title>$Domain</title><h1>$Domain hazır</h1></html>" | Set-Content -Path (Join-Path $FizikselYol "index.html") -Encoding UTF8
if (-not (Test-Path "IIS:\AppPools\$HavuzAdi")) {
New-WebAppPool -Name $HavuzAdi | Out-Null
}
if (-not (Test-Path "IIS:\Sites\$SiteAdi")) {
New-Website -Name $SiteAdi -Port 80 -IPAddress "*" -HostHeader $Domain -PhysicalPath $FizikselYol -ApplicationPool $HavuzAdi | Out-Null
New-WebBinding -Name $SiteAdi -Protocol http -Port 80 -IPAddress "*" -HostHeader "www.$Domain" | Out-Null
}
& icacls $FizikselYol /grant "IIS_IUSRS:(OI)(CI)(RX)" /T /C | Out-Null
"$Domain,basarili,$SiteAdi,$HavuzAdi,$FizikselYol" | Add-Content -Path $SonucDosyasi -Encoding UTF8
}
catch {
"$Domain | $($_.Exception.Message)" | Add-Content -Path $ErrorDosyasi -Encoding UTF8
"$Domain,errorli,$SiteAdi,$HavuzAdi,$FizikselYol" | Add-Content -Path $SonucDosyasi -Encoding UTF8
}
}
Get-Website | Select-Object Name,State,PhysicalPath,Bindings
Write-Host "Tamamlandı: $SonucDosyasi"
Write-Host "Errorlar: $ErrorDosyasi"
For domains serving the same application, add a binding instead of a new IIS site.
New-WebBinding -Name "AnaSite" -Protocol http -Port 80 -IPAddress "*" -HostHeader "alias-domain.com"
New-WebBinding -Name "AnaSite" -Protocol http -Port 80 -IPAddress "*" -HostHeader "www.alias-domain.com"
On systems using the newer module, New-IISSite can create a site with bindingInformation.
Import-Module IISAdministration
New-IISSite -Name "eka-ornek.com" -PhysicalPath "C:\inetpub\siteler\ornek.com" -BindingInformation "*:80:ornek.com"
List duplicate protocol, IP, port and host combinations.
Get-WebBinding | ForEach-Object { [PSCustomObject]@{ Site=$_.ItemXPath; Protocol=$_.protocol; Binding=$_.bindingInformation } } | Group-Object Protocol,Binding | Where-Object Count -gt 1
WebAdministration is common and stable. Check TLS versions, .NET Hosting Bundle and URL Rewrite based on the application.
Get-WindowsFeature Web-ServerGet-Module WebAdministration -ListAvailableiisreset /statusA suitable production choice for SNI, modern TLS and current .NET hosting. Monitor app-pool behavior after Windows Update.
Get-ComputerInfo | Select WindowsProductName,WindowsVersionGet-WebAppPoolState -Name *Get-TlsCipherSuite | Select-Object -First 10Use WebAdministration or IISAdministration according to installed role versions and test automation in staging.
Get-WindowsFeature Web-Server,Web-Mgmt-ToolsGet-Command New-Website,New-IISSite -ErrorAction SilentlyContinueGet-IISSite 2>$nullThe same IIS site name, binding or physical path may already exist.
WebAdministration may not be installed or PowerShell may not be elevated.
web.config syntax, locked sections, missing modules or NTFS access may be the problem.
The application pool may be stopped, Rapid-Fail Protection triggered or the runtime failed to load.
The same IP:port:host combination may exist on another site or a blank host header may conflict.
No matching error was found.
No. It provides isolation for different customers or applications; low-traffic alias sites within one trust boundary can share a pool.
It is technically possible when they serve the same application. Design certificate/SNI, logging, canonical and redirect strategy separately.
Obtain and install the certificate in the LocalMachine store, then bind an SNI host binding using its thumbprint. Manage certificate lifecycle separately.
Yes, with FastCGI and proper PHP configuration. Standardize PHP handlers, request timeouts and file permissions separately from domain creation.
If the DNS role is on the server, cmdlets such as Add-DnsServerResourceRecordA can be used. External DNS or Cloudflare requires a separate provider API workflow.
No. Technical foundations, original copy, multilingual URLs and structured data support visibility but do not guarantee rankings.
We implement panel selection, DNS, SSL, web server, security, backup and verification according to your actual server architecture.