IntermediateLesson 5 of 16

What is IIS and How It Works

Internet Information Services — Microsoft's production-grade web server since 1995. Understand its version history, component model, the roles it plays in .NET hosting, and why it remains the dominant Windows web server in enterprise environments.

🧒 Simple Explanation (ELI5)

IIS is like a professional hotel lobby receptionist. When a guest (web browser) arrives and says "I'd like a room" (HTTP request), the receptionist (IIS) checks the reservation system (routing rules), finds the right room (web application), and escorts the guest to the correct floor (routes to the correct app pool and application). The receptionist stays at the lobby (HTTP.sys kernel listener) no matter how many guests they handle simultaneously.

🔧 Why Do We Need It?

🌍 Real-world Analogy

IIS is like a multi-storey office building directory service. Visitors (HTTP requests) arrive at the lobby (HTTP.sys) and tell the reception (IIS) their destination: "I'm here for Contoso HR" or "I'm visiting Fabrikam IT." IIS checks its floor directory (site bindings and host headers), directs the visitor to the right elevator (routes to the correct application pool), and ensures each company's floor is locked from other floors (process isolation). The building management office (IIS Manager) lets administrators add floors, change access rules, and monitor occupancy.

⚙️ Technical Explanation

IIS (Internet Information Services) ships as a Windows Server role called "Web Server (IIS)." It consists of two major service processes: W3SVC (World Wide Web Publishing Service) manages the overall service configuration, and WAS (Windows Process Activation Service) creates and manages worker processes on demand. The kernel-mode driver HTTP.sys handles raw TCP/IP and HTTP protocol processing at the network stack level before any user-mode code runs.

IIS serves four types of content: static files (HTML, CSS, JS, images — served directly from disk without invoking any .NET code), ISAPI handlers (legacy ASP, CGI extensions), managed .NET handlers (ASP.NET Framework via the CLR pipeline integrated into IIS), and ANCM (ASP.NET Core Module) where IIS acts as a reverse proxy forwarding requests to a Kestrel process (out-of-process) or hosting the Core app directly in worker process memory (in-process, introduced in ASP.NET Core 2.2).

The IIS request pipeline is a sequence of modules: Authentication → Authorization → Response Cache → Static File Handler → Request Filtering → Handler Mapping → ManagedEngine (If ASP.NET). Each module can inspect or modify the request/response. You can add custom native modules (C++ DLLs) or managed modules (.NET classes implementing IHttpModule) to intercept and process requests at any pipeline stage.

⚠️
IIS Versions — What Ships with What Windows Version

IIS 6.0 = Windows Server 2003 (legacy, w3wp but no WAS). IIS 7.0 = Windows Server 2008 (introduced WAS, modular pipeline, unified config). IIS 7.5 = Windows Server 2008 R2 (virtual accounts, improved app pool identity). IIS 8.0 = Windows Server 2012 (SNI, central SSL store, WebSockets). IIS 8.5 = Windows Server 2012 R2 (enhanced logging, ETW tracing). IIS 10.0 = Windows Server 2016/2019/2022 (HTTP/2, Wildcard Host Headers, Let's Encrypt support via ACME, TLS 1.3 on Server 2022). Always check the IIS version before troubleshooting — features like SNI, HTTP/2, and WebSockets availability depend on it: %windir%\system32\inetsrv\iis.msc → Help → About.

📊 Visual Representation

IIS Component Model
Management Layer
IIS Manager (inetmgr)
PowerShell WebAdministration
appcmd.exe
Web Deploy (msdeploy)
Configuration
applicationHost.config
web.config (per-site/app)
machine.config (.NET)
redirection.config
Runtime Layer
W3SVC (service coordination)
WAS (process activation)
w3wp.exe (worker process)
CLR / ANCM (for .NET apps)
Network Layer
HTTP.sys (kernel mode)
TCP/IP Stack
SSL/TLS offload
Response cache

⌨️ Commands / Syntax

cmd / PowerShell
# --- Install IIS (Windows Server) ---
Install-WindowsFeature -Name Web-Server -IncludeManagementTools

# Install all common IIS features for ASP.NET hosting
Install-WindowsFeature Web-Server,Web-Common-Http,Web-Asp-Net45,Web-Net-Ext45,
  Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Includes,Web-Health,Web-Performance,
  Web-Mgmt-Console,Web-Scripting-Tools -IncludeManagementTools

# --- Verify IIS installation ---
Get-WindowsFeature Web-Server
(Get-Item -Path "HKLM:\SOFTWARE\Microsoft\InetStp").GetValue("MajorVersion")
$env:SystemRoot + "\system32\inetsrv\iissetup.exe" # IIS setup binary path

# --- appcmd reference ---
%windir%\system32\inetsrv\appcmd list site        # List all sites
%windir%\system32\inetsrv\appcmd list app         # List all applications
%windir%\system32\inetsrv\appcmd list vdir        # List virtual directories
%windir%\system32\inetsrv\appcmd list apppool     # List all app pools
%windir%\system32\inetsrv\appcmd list wp          # List worker processes + PIDs

# --- PowerShell WebAdministration module ---
Import-Module WebAdministration
Get-Website                            # List all websites
Get-WebApplication                     # List all web applications
Get-WebAppPoolState -Name DefaultAppPool
Get-ChildItem IIS:\Sites               # IIS provider drive

# --- IISRESET ---
iisreset                        # Stop and restart all IIS services
iisreset /start                 # Start IIS services
iisreset /stop                  # Stop IIS services only
iisreset /status                # Show current IIS service states
iisreset /noforce               # Graceful stop (won't force if connections active)

💼 Example (Real-world Use Case)

A company migrates from IIS 8.5 (Server 2012 R2) to IIS 10.0 (Server 2019) to enable HTTP/2 for their high-traffic e-commerce site. After migration, the DevOps engineer validates: (1) runs appcmd list site /processModel.userName:applicationPoolIdentity to confirm all pools use managed identities. (2) opens browser DevTools → Network to confirm H2 protocol in the Protocol column on HTTPS requests. (3) checks netsh http show servicestate to confirm all sites re-registered in HTTP.sys. (4) verifies TLS 1.0/1.1 are disabled (Server 2019 default). The site now serves pages 30% faster due to multiplexed HTTP/2 connections with header compression.

🧪 Hands-on

  1. Open Server Manager → Add Roles and Features → install "Web Server (IIS)" with at minimum: Common HTTP Features, Health and Diagnostics (logging + request monitoring), Performance (static compression), Security (IP/domain filtering), Application Development (ASP.NET 4.5, .NET Extensibility 4.5), and Management Tools (IIS Management Console).
  2. After installation, open IIS Manager (Win+R → inetmgr). Expand the Connections pane: verify you see Sites → Default Web Site. Click it and press Browse — confirm the IIS welcome page appears in your browser.
  3. Run appcmd list site and appcmd list apppool from an elevated Command Prompt. Note the Default Web Site bound to port 80 and DefaultAppPool in the Started state.
  4. Run sc query w3svc and sc query was — confirm both are Running. Then run sc query http to confirm the kernel driver is loaded.
  5. Import the WebAdministration module in PowerShell: Import-Module WebAdministration; Get-Website | Format-List. Examine the output — note the ID, Name, Bindings, State, and PhysicalPath properties that map to what you see in IIS Manager.
💡
IIS on Windows vs Server Core

Modern deployments prefer Windows Server Core for IIS because it has a smaller attack surface, lower memory footprint, and requires fewer monthly patches. On Server Core, manage IIS remotely via IIS Manager's remote management feature (requires installing IIS Management Service and opening port 8172 on the firewall) or via PowerShell WebAdministration module remoted over WinRM. This is the production-recommended pattern for new IIS deployments in enterprise and cloud environments.

🐛 Debugging Scenario

Failure: After installing IIS, the Default Web Site stops immediately after starting. IISRESET says services are running, but browsing localhost returns "This site can't be reached."

🎯 Interview Questions

Beginner

What is IIS and what does it do?

IIS (Internet Information Services) is Microsoft's web server component included with Windows. It receives HTTP/HTTPS requests from clients, routes them to the appropriate web application or file resource, and returns the response. It handles static file serving, ASP.NET application hosting, SSL/TLS termination, authentication, compression, request logging, and URL rewriting. IIS runs as a Windows service (W3SVC) and is managed through IIS Manager GUI, PowerShell, or command-line tools like appcmd. It is the standard web server for .NET Framework applications and is widely used for hosting ASP.NET Core, PHP, and static sites on Windows Server.

What is the Default Web Site in IIS?

The Default Web Site is the web site that IIS creates automatically when installed. It is bound to port 80 on all IP addresses (*:80) and serves content from C:\inetpub\wwwroot. It runs in the DefaultAppPool application pool. In a fresh IIS installation, browsing http://localhost returns the IIS welcome page (iisstart.htm). In production environments, the Default Web Site is often either deleted or repurposed — deploying actual applications as separate sites with their own bindings, application pools, and physical paths rather than placing content directly in wwwroot. Leaving the default site active without content exposes a recognisable IIS fingerprint to reconnaissance tools.

What is IISRESET and when should you use it?

IISRESET is a command-line tool that stops and restarts all IIS services: W3SVC, WAS, and the related HTTP listeners. It is used after: configuration changes that require service restart (most config changes in IIS are hot-loaded and do NOT require iisreset — only changes to the applicationHost.config schema or global module registration need a restart). Also used when IIS is in a stuck/degraded state that prevents normal operation. Warning: iisreset drops all active connections to all hosted sites simultaneously — on a busy production server this causes a traffic spike to load balancer fallbacks and session loss for stateful apps. For production, prefer recycling the specific app pool (appcmd recycle apppool /apppool.name:MyPool) rather than a full iisreset.

What is an IIS Site vs an Application vs a Virtual Directory?

Site (top-level): A named container that has one or more bindings (IP:port:hostname combinations) and a root application. Each site maps to a physical directory on disk. Application: A named sub-path within a site that runs in its own application pool and has its own web.config. For example, a site at http://example.com could have an application at /api/ running in a separate app pool with a different .NET version. Virtual Directory: An alias path within an application that maps to a physical directory elsewhere on disk (e.g., /images → D:\SharedImages). Virtual directories do not run code — they just provide a URL path to filesystem mapping. A site contains applications; an application contains virtual directories.

What is the difference between IIS and Kestrel for ASP.NET Core?

Kestrel is the lightweight, cross-platform web server built into ASP.NET Core itself. IIS is the full-featured Windows web server. In production on Windows, they are typically used together in two patterns: Out-of-process: IIS receives HTTP requests and forwards them to a separate Kestrel process via the ASP.NET Core Module (ANCM). Kestrel handles the .NET runtime. IIS handles SSL termination, authentication, URL rewriting, and static files. In-process: IIS hosts the .NET runtime directly inside w3wp.exe via ANCM in-process hosting — better performance but the application lifecycle is coupled to the w3wp process. In-process is the default for ASP.NET Core 3.0+. Kestrel alone is not recommended for direct internet exposure — it lacks the security hardening, logging, and management features of IIS.

Intermediate

What is the IIS request pipeline and what are modules?

The IIS request pipeline is the ordered sequence of processing stages a request passes through. There are 19 defined request processing stages from BeginRequest to EndRequest. At each stage, registered IIS modules can execute code. Modules are of two types: Native modules — C++ DLLs registered as IIS modules (e.g., RequestFilteringModule, StaticFileModule, AnonymousAuthenticationModule, HttpLoggingModule). These run with almost no overhead. Managed modules — .NET classes implementing IHttpModule, registered in web.config. These run only in Integrated Pipeline mode. The most critical modules: StaticFileModule, DefaultDocumentModule, DirectoryBrowsingModule, AnonymousAuthenticationModule, ManagedEngine (loads CLR for .NET requests). Missing a module causes 404.7 or 500.19 errors depending on what was referenced in config.

How does IIS handle multiple versions of .NET on the same server?

Each application pool specifies a .NET CLR version (No Managed Code, v2.0, or v4.0) and a managed pipeline mode (Classic or Integrated). v2.0 includes .NET 2.0, 3.0, and 3.5. v4.0 includes .NET 4.0 through 4.8.x. For ASP.NET Core, the .NET version is handled within the w3wp process via the ANCM — set pool to "No Managed Code" and the ANCM bootstraps the correct Core runtime version as specified in the app's runtimeconfig.json. This means you can host .NET Framework 3.5, .NET 4.8, and ASP.NET Core 8.0 simultaneously on the same IIS server by placing each application in a separate pool with the correct settings.

What is Application Request Routing (ARR) and when would you use it?

ARR (Application Request Routing) is an IIS extension that turns IIS into a reverse proxy and load balancer. It can distribute incoming requests across a server farm (multiple backend web servers), provide health monitoring and failover, implement content-based routing (route /api/ to one farm and /static/ to another), and enable URL rewriting at the proxy layer. Use cases: IIS as a front-end reverse proxy in front of multiple application servers, enabling HTTPS termination at one point for a farm, blue-green deployment by routing traffic to new/old server groups, and providing a single entry point for multiple backend services. ARR pairs with the URL Rewrite module to define routing rules in web.config.

What IIS features are needed specifically for ASP.NET application hosting?

For ASP.NET Framework: Web-Asp-Net (ASP.NET 3.5), Web-Asp-Net45 (ASP.NET 4.5+), Web-Net-Ext (for 2.0/3.5 extensibility), Web-Net-Ext45 (for 4.x extensibility), Web-ISAPI-Ext, Web-ISAPI-Filter. After installing features, run aspnet_regiis -iru to register ASP.NET with IIS (required on Server 2008, not needed on 2012+). For ASP.NET Core: install the .NET Core Hosting Bundle (which includes ANCM), set the app pool to "No Managed Code". Without the Hosting Bundle, ASP.NET Core apps return HTTP 500.0 or 502.5. For both: ensure the IIS application pool's .NET CLR version matches the framework — using v4.0 CLR for a .NET 4.8 app, or No Managed Code for Core apps.

What is the difference between Classic and Integrated Pipeline mode in IIS?

Classic mode (legacy, IIS 6 compatibility): ASP.NET is invoked as an ISAPI extension, running outside the IIS native pipeline. Managed modules (IHttpModule) only execute for requests that match ASP.NET handler extensions (.aspx, .asmx etc.) — not for static files or PHP requests. Integrated mode (IIS 7+): the ASP.NET pipeline is unified with the IIS native pipeline. Managed modules can intercept ALL requests regardless of file extension, enabling global auth, logging, and processing for static files, images, and any URL. Integrated mode is required for many modern ASP.NET features — use Classic only for legacy apps that explicitly break in Integrated mode (typically very old ISAPI-dependent apps from the IIS 5/6 era). New applications should always use Integrated mode.

Scenario-based

You are handed an IIS server with 15 sites. How do you get a quick inventory of what is running, what framework version each app uses, and which pools are stopped?

Single PowerShell script: Import-Module WebAdministration; Get-Website | Select-Object Name,State,@{N='Bindings';E={($_.Bindings.Collection | Select-Object -ExpandProperty bindingInformation) -join ','}}; Get-ChildItem IIS:\AppPools | Select-Object Name,State,@{N='NetVersion';E={$_.ManagedRuntimeVersion}},@{N='PipelineMode';E={$_.ManagedPipelineMode}}. This renders a table of: all sites with their states and bindings, all pools with their .NET version, pipeline mode, and started/stopped state. Stopped pools (State = Stopped) indicate an app pool disabled due to too many crashes (check Event ID 5010 in Application log) — these are the sites currently returning 503. Combine with appcmd list wp to see which pools currently have running worker processes vs. which have not received requests yet.

An ASP.NET Core app works fine locally but returns HTTP 502.5 on IIS. What do you check?

HTTP 502.5 is "ANCM Out-Of-Process Startup Failure" — the ASP.NET Core Module tried to start the application process (Kestrel or the Core web host) but failed. Check in order: (1) Is the .NET Core Hosting Bundle installed on the server? dotnet --info from command prompt on the server. If missing, install from Microsoft. (2) Is the app pool configured as "No Managed Code"? The CLR version must be No Managed Code for Core apps. (3) Can the application binary run directly? Navigate to site root, run dotnet MyApp.dll — the error message from dotnet run is more informative than IIS's 502. (4) Check stdout logs: in web.config set stdoutLogEnabled=true and stdoutLogFile=.\logs\stdout — this captures the Core startup exception. (5) Check Event Viewer Application log for Application Error or ANCM events detailing the startup failure.

How would you migrate a site from IIS on Server 2012 R2 to IIS on Server 2019?

Use Web Deploy (msdeploy): (1) Install Web Deploy 3.6 on both servers. (2) On source: msdeploy -verb:sync -source:webServer -dest:package=C:\backup\site.zip. (3) On destination: msdeploy -verb:sync -source:package=C:\backup\site.zip -dest:webServer. The package includes site configurations, applications, virtual directories, SSL certificate bindings (certs must be re-imported separately — export from source cert store), and application pool settings. Post-migration: verify .NET frameworks needed by the app are installed on the new server, confirm NTFS permissions are correct for new pool identities, update DNS to point to new server IP, run smoke tests, and monitor Event Viewer for the first 30 minutes. Keep the old server running for at least 24 hours in case rollback is needed.

Your IIS server is in production and the team asks why IISRESET takes several minutes to complete. What could cause this?

IISRESET stops W3SVC, which signals all w3wp.exe worker processes to stop. Long stop time causes: (1) Active long-running requests — w3wp waits up to the shutdown time limit (default 90 seconds) for in-flight requests to complete before forcibly terminating. Many slow requests = long shutdown. Reduce with app pool Advanced Settings → Shutdown Time Limit. (2) Application-level shutdown logic — .NET applications handle Application_End in Global.asax, which may do cleanup work (flush caches, close database connections). (3) Many app pools — if 15 pools each take 5 seconds to shut down sequentially, total = 75 seconds. IISRESET /noforce doesn't force stop, making this worse. Solution for production: never run full iisreset — recycle individual pools with appcmd recycle apppool /apppool.name:xxx, which does a graceful replacement without dropping connections to other pools.

A site worked fine for 6 months but after a .NET Framework update it now crashes on startup. How do you roll back?

Immediate: recycle the app pool — if the .NET update introduced a new default in machine.config that conflicts with the app's web.config, the pool may crash once and then stabilise. If it keeps crashing: check Event 1000 in Application log for the faulting assembly. Identify if it's a CLR assembly (mscorlib, System.Web) vs application assembly. For .NET patch rollback: Windows Update allows individual update uninstall. Open Settings → Update and Security → View Update History → Uninstall Updates. Find the .NET Framework cumulative update and uninstall it. Reboot or run iisreset. Note: in enterprise environments, coordinate .NET update rollback with WSUS team and document in change management. Long-term: establish a staging environment that receives .NET patches 5 business days before production — this is the standard enterprise practice for catching regression before production impact.

🌐 Real-world Usage

IIS powers hundreds of millions of websites including Microsoft's own product sites, large-scale enterprise intranets, banking portals, government systems, and healthcare applications. It is the default choice whenever a company's infrastructure runs on Active Directory and .NET Framework/Core — the combination of native Windows auth, enterprise-grade SSL handling, and native .NET CLR integration makes it unmatched for those workloads.

📝 Summary

IIS 10.0 is a full-featured enterprise web server with a modular request pipeline, kernel-mode HTTP.sys listener, and deep .NET Framework and .NET Core integration. It manages sites, applications, and application pools as independent units. Understanding its component model is the prerequisite for all IIS configuration, security, and troubleshooting work.