How to Install and Configure IIS on Windows Server 2012 R2

Internet Information Services (IIS) 8.5 ships with Windows Server 2012 R2 and is the most widely deployed web server on the Microsoft platform. IIS 8.5 includes significant improvements over earlier versions: dynamic IP restrictions, enhanced logging, ETW tracing for real-time diagnostics, application initialisation (warm-up), and idle worker process page-out. Whether you are hosting ASP.NET applications, PHP via FastCGI, static HTML sites, or acting as a reverse proxy, IIS 8.5 provides a mature, production-grade platform.

This guide covers installing IIS with a full feature set, creating web sites and application pools, configuring HTTPS with SSL certificates, setting up authentication, enabling compression, and hardening the server against common web attacks.

Prerequisites

  • Windows Server 2012 R2 with static IP address.
  • Port 80 and 443 open in Windows Firewall and any upstream firewalls.
  • DNS record pointing your site’s hostname to the server’s IP.
  • An SSL certificate (self-signed or CA-issued) for HTTPS sites.
  • Administrator account.

Step 1: Install IIS with Full Feature Set

# Install IIS with the most commonly needed features
Install-WindowsFeature -Name `
    Web-Server, `
    Web-WebServer, `
    Web-Common-Http, `
    Web-Default-Doc, `
    Web-Dir-Browsing, `
    Web-Http-Errors, `
    Web-Static-Content, `
    Web-Http-Redirect, `
    Web-Health, `
    Web-Http-Logging, `
    Web-Log-Libraries, `
    Web-Request-Monitor, `
    Web-Http-Tracing, `
    Web-Performance, `
    Web-Stat-Compression, `
    Web-Dyn-Compression, `
    Web-Security, `
    Web-Filtering, `
    Web-Basic-Auth, `
    Web-Windows-Auth, `
    Web-App-Dev, `
    Web-Net-Ext45, `
    Web-Asp-Net45, `
    Web-ISAPI-Ext, `
    Web-ISAPI-Filter, `
    Web-Mgmt-Tools, `
    Web-Mgmt-Console, `
    Web-Mgmt-Service, `
    NET-Framework-45-ASPNET `
    -IncludeManagementTools

# Verify IIS is running
Get-Service -Name W3SVC | Select-Object Name, Status

# Check IIS version
Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftInetStp" | 
    Select-Object MajorVersion, MinorVersion, VersionString

Step 2: Understand the IIS Structure

IIS uses a hierarchical structure: the server hosts one or more Sites, each site runs in an Application Pool, and each site can contain multiple Applications. Understanding this hierarchy is essential before creating anything.

# Import IIS administration module
Import-Module WebAdministration

# List existing sites
Get-Website | Select-Object Name, State, PhysicalPath, Bindings

# List application pools
Get-WebConfiguration -Filter "system.applicationHost/applicationPools/add" | 
    Select-Object Name, State, ManagedRuntimeVersion, ManagedPipelineMode

# View the Default Web Site
Get-Website -Name "Default Web Site"

Step 3: Create a New Application Pool and Web Site

# Create a dedicated application pool for a new site
New-WebAppPool -Name "CorpSite-AppPool"

# Configure the app pool: .NET 4.5, Integrated pipeline, recycle at midnight
Set-ItemProperty -Path "IIS:AppPoolsCorpSite-AppPool" -Name managedRuntimeVersion -Value "v4.0"
Set-ItemProperty -Path "IIS:AppPoolsCorpSite-AppPool" -Name managedPipelineMode -Value "Integrated"
Set-ItemProperty -Path "IIS:AppPoolsCorpSite-AppPool" -Name processModel.idleTimeout -Value "00:20:00"

# Set the app pool to recycle at 02:00 AM
$appPool = Get-Item "IIS:AppPoolsCorpSite-AppPool"
$appPool.Recycling.PeriodicRestart.Schedule.Clear()
$appPool.Recycling.PeriodicRestart.Schedule.Add("02:00:00")
$appPool | Set-Item

# Create the web site directory
New-Item -Path "D:Websitescorpsite.example.com" -ItemType Directory

# Create the web site
New-Website `
    -Name "corpsite.example.com" `
    -PhysicalPath "D:Websitescorpsite.example.com" `
    -ApplicationPool "CorpSite-AppPool" `
    -Port 80 `
    -HostHeader "corpsite.example.com"

# Start the web site
Start-Website -Name "corpsite.example.com"

Step 4: Configure HTTPS with SSL

# Create a self-signed certificate for testing
$cert = New-SelfSignedCertificate `
    -DnsName "corpsite.example.com" `
    -CertStoreLocation "cert:LocalMachineMy" `
    -KeyExportPolicy Exportable `
    -KeySpec Signature `
    -KeyLength 2048 `
    -HashAlgorithm SHA256

# Add an HTTPS binding to the web site
New-WebBinding `
    -Name "corpsite.example.com" `
    -Protocol "https" `
    -Port 443 `
    -HostHeader "corpsite.example.com"

# Assign the certificate to the HTTPS binding
$binding = Get-WebBinding -Name "corpsite.example.com" -Protocol "https"
$binding.AddSslCertificate($cert.Thumbprint, "my")

# Redirect HTTP to HTTPS using URL Rewrite (requires URL Rewrite module)
# Or use a simple web.config redirect:
$webConfig = @"


  
    
  

"@
$webConfig | Out-File -FilePath "D:Websitescorpsite.example.comweb.config" -Encoding UTF8

Step 5: Configure Authentication

# Disable Anonymous Authentication (enable Windows Auth for internal app)
Set-WebConfigurationProperty `
    -Filter "system.webServer/security/authentication/anonymousAuthentication" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name enabled -Value $false

Set-WebConfigurationProperty `
    -Filter "system.webServer/security/authentication/windowsAuthentication" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name enabled -Value $true

# Enable Basic Authentication (for external apps with HTTPS)
Set-WebConfigurationProperty `
    -Filter "system.webServer/security/authentication/basicAuthentication" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name enabled -Value $true

# Verify authentication settings
Get-WebConfigurationProperty `
    -Filter "system.webServer/security/authentication/*" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name enabled

Step 6: Enable Compression and Configure Logging

# Enable static and dynamic content compression
Set-WebConfigurationProperty `
    -Filter "system.webServer/httpCompression" `
    -PSPath "IIS:" `
    -Name staticCompressionLevel -Value 9

Set-WebConfigurationProperty `
    -Filter "system.webServer/httpCompression" `
    -PSPath "IIS:" `
    -Name dynamicCompressionLevel -Value 4

# Configure W3C extended logging with useful fields
Set-WebConfigurationProperty `
    -Filter "system.applicationHost/sites/site[@name='corpsite.example.com']/logFile" `
    -PSPath "IIS:" `
    -Name directory -Value "D:LogsIIS"

Set-WebConfigurationProperty `
    -Filter "system.applicationHost/sites/site[@name='corpsite.example.com']/logFile" `
    -PSPath "IIS:" `
    -Name logFormat -Value "W3C"

# Flush IIS log buffers
netsh http flush logbuffer

Step 7: Security Hardening

# Remove the Server header from HTTP responses
Set-WebConfigurationProperty `
    -Filter "system.webServer/security/requestFiltering" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name allowHighBitCharacters -Value $false

# Limit maximum request size (50 MB)
Set-WebConfigurationProperty `
    -Filter "system.webServer/security/requestFiltering/requestLimits" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name maxAllowedContentLength -Value 52428800

# Enable dynamic IP restrictions to block brute force
Set-WebConfigurationProperty `
    -Filter "system.webServer/security/dynamicIpSecurity" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name denyAction -Value "Forbidden"

Set-WebConfigurationProperty `
    -Filter "system.webServer/security/dynamicIpSecurity/denyByRequestRate" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name enabled -Value $true

Set-WebConfigurationProperty `
    -Filter "system.webServer/security/dynamicIpSecurity/denyByRequestRate" `
    -PSPath "IIS:Sitescorpsite.example.com" `
    -Name maxRequests -Value 100

# Hide IIS version from error pages (already set in IIS 8.5 by default)
Set-WebConfigurationProperty `
    -Filter "system.webServer/httpErrors" `
    -PSPath "IIS:" `
    -Name errorMode -Value "DetailedLocalOnly"

Summary

IIS 8.5 on Windows Server 2012 R2 is a production-ready web platform with extensive configuration options accessible through both the graphical IIS Manager and the WebAdministration PowerShell module. The essential setup tasks are: install the required IIS role services for your application type, create dedicated application pools for each site, configure HTTPS bindings with certificates, choose appropriate authentication methods, enable content compression for performance, configure logging to a non-system volume, and apply security hardening such as request filtering and dynamic IP restrictions. For production deployments, always keep application pools running under least-privilege service accounts and never run them as LocalSystem or NetworkService.