How to Create a New IIS Website on Windows Server 2025 Print

  • Windows, PowerShell, Administration, IIS
  • 0

Overview

This guide covers the recommended folder layout, IIS configuration steps, and an optional PowerShell script to automate the setup of a new IIS website on Windows Server 2025.

Best Practice Folder Layout

  • Create one folder per site outside of wwwroot
  • Example: C:\inetpub\MyNewSite

Step 1 - Create the Site Folder

  1. Create the folder for your site (example: C:\inetpub\MyNewSite)
  2. Place your site files inside this folder

Step 2 - Create a Dedicated Application Pool

  1. Open IIS Manager
  2. Navigate to Application Pools and click Add Application Pool
  3. Configure the following:
    • Name: MyNewSiteAppPool
    • .NET CLR: use the required runtime, or select No Managed Code for static sites
    • Pipeline: Integrated

Step 3 - Set NTFS Permissions on the Site Folder

  1. Grant Modify permissions to the App Pool identity only: IIS AppPool\MyNewSiteAppPool
  2. Remove unnecessary write permissions for Users or Everyone

Step 4 - Add the Website

  1. In IIS Manager, navigate to Sites and click Add Website
  2. Configure the following:
    • Site name: MyNewSite
    • Application pool: MyNewSiteAppPool
    • Physical path: C:\inetpub\MyNewSite
    • Binding: HTTP on port 80 with a host name (example: mynewsite.local)

Step 5 - Add HTTPS (Optional)

  1. Add an HTTPS binding and select a certificate when available
  2. See the separate certificate guide for full details

Step 6 - Test Locally

  1. Add a hosts file entry for testing: 127.0.0.1 mynewsite.local
  2. Browse to http://mynewsite.local or https://mynewsite.local to confirm the site loads

PowerShell Script - Create Folder, App Pool, Site, and Permissions

Run the following in an elevated PowerShell session to automate the full setup:

# Variables
$SiteName       = "MyNewSite"
$AppPool        = "MyNewSiteAppPool"
$PhysicalPath   = "C:\inetpub\MyNewSite"
$HttpHost       = "mynewsite.local"
$HttpPort       = 80

Import-Module WebAdministration

# 1) Create folder if it does not exist
if (-not (Test-Path -LiteralPath $PhysicalPath)) {
    New-Item -ItemType Directory -Path $PhysicalPath | Out-Null
}

# 2) Create a dedicated Application Pool
if (-not (Test-Path IIS:\AppPools\$AppPool)) {
    New-WebAppPool -Name $AppPool | Out-Null
    Set-ItemProperty "IIS:\AppPools\$AppPool" -Name "managedPipelineMode" -Value "Integrated"
    # Use No Managed Code for static sites:
    # Set-ItemProperty "IIS:\AppPools\$AppPool" -Name "managedRuntimeVersion" -Value ""
}

# 3) Grant NTFS permissions to the App Pool identity
$aclCmd = 'icacls "{0}" /grant "IIS AppPool\{1}:(OI)(CI)(M)" /T' -f $PhysicalPath, $AppPool
cmd.exe /c $aclCmd

# 4) Create the website and bind HTTP
if (-not (Get-Website -Name $SiteName -ErrorAction SilentlyContinue)) {
    New-Website -Name $SiteName -PhysicalPath $PhysicalPath -Port $HttpPort -HostHeader $HttpHost -ApplicationPool $AppPool | Out-Null
} else {
    if (-not (Get-WebBinding -Name $SiteName -Protocol "http" -ErrorAction SilentlyContinue | Where-Object { $_.bindingInformation -match ":$HttpPort:$HttpHost" })) {
        New-WebBinding -Name $SiteName -Protocol "http" -Port $HttpPort -HostHeader $HttpHost | Out-Null
    }
}

Write-Host "Site '$SiteName' created and bound to http://$HttpHost:$HttpPort"

Optional - Create a Self-Signed Certificate and Add HTTPS Binding

For quick internal testing, use the following script to generate a self-signed certificate and bind it to HTTPS:

$HttpsPort     = 443
$DnsName       = $HttpHost

$cert = New-SelfSignedCertificate -DnsName $DnsName -CertStoreLocation "cert:\LocalMachine\My" -FriendlyName "$SiteName SelfSigned" -KeyLength 2048 -HashAlgorithm sha256 -KeyExportPolicy Exportable -NotAfter (Get-Date).AddYears(1)

if (-not (Get-WebBinding -Name $SiteName -Protocol "https" -ErrorAction SilentlyContinue | Where-Object { $_.bindingInformation -match ":$HttpsPort:$DnsName" })) {
    New-WebBinding -Name $SiteName -Protocol "https" -Port $HttpsPort -HostHeader $DnsName | Out-Null
}

$bindingPath = "IIS:\SslBindings.0.0.0!$HttpsPort!$DnsName"
if (-not (Test-Path $bindingPath)) {
    New-Item $bindingPath -Thumbprint $cert.Thumbprint -SSLFlags 1 | Out-Null
} else {
    Set-Item -Path $bindingPath -Thumbprint $cert.Thumbprint -SSLFlags 1
}

Write-Host "HTTPS binding added for https://$DnsName:$HttpsPort using a self-signed certificate."

Notes

  • Always run PowerShell as Administrator when executing these scripts
  • For production environments, use a trusted CA certificate - self-signed certificates will trigger browser warnings
  • Keep one site per Application Pool for better process isolation and security

Was this answer helpful?

« Back