IIS – Webserver Grundlagen
Internet Information Services (IIS) als Windows-Webserver einrichten, konfigurieren und betreiben – von der Installation bis zu SSL und Troubleshooting.
Was ist IIS und wann brauchst du ihn?
IIS (Internet Information Services) ist Microsofts eingebauter Webserver, der seit Windows NT mit dabei ist. Ab Windows Server 2008 R2 läuft er als IIS 7.0 oder höher mit einer vollständig modularen Architektur – du aktivierst nur, was du wirklich brauchst.
Als IT-Allrounder in einem KMU begegnest du IIS vor allem in diesen Szenarien:
- Interne Webanwendungen hosten (z. B. ERP-Webfrontend, Intranet, Confluence-Alternativen)
- Webdienste für Partner oder Kunden bereitstellen (REST-APIs, klassische ASP.NET-Apps)
- Redirect-Server für interne URLs einrichten
- Zertifikatsdienste (ADCS) oder WSUS über HTTPS veröffentlichen
- Legacy-Applikationen mit klassischem ASP oder .NET Framework betreiben
IIS ist kein Apache oder nginx – er ist tief in Windows integriert, nutzt Windows-Authentifizierung direkt und lässt sich per PowerShell und GPO steuern. Wenn du eine Windows-lastiges Umfeld hast, ist IIS oft die einfachste Wahl.
IIS installieren
IIS ist eine Windows Server-Rolle, die du über den Server-Manager oder PowerShell aktivierst. Sie ist nicht standardmässig aktiv.
Minimalinstallation (nur Webserver):
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Erweiterte Installation für .NET-Anwendungen:
# Webserver inkl. .NET 4.5 und ASP.NET
Install-WindowsFeature -Name Web-Server, Web-Asp-Net45, Web-Net-Ext45 -IncludeManagementTools
# Alle gängigen Features auf einmal (typischer App-Server)
Install-WindowsFeature -Name Web-Server `
-IncludeAllSubFeature `
-IncludeManagementTools
Installation prüfen:
Get-WindowsFeature -Name Web-* | Where-Object { $_.Installed -eq $true }
Nach der Installation erreichst du den IIS Manager so:
inetmgr
Oder: Win+R → inetmgr → Enter.
Kernkonzepte im Überblick
Bevor du loslegst, musst du diese fünf Begriffe verstehen. Alles andere baut darauf auf:
| Begriff | Was es ist |
|---|---|
| Site | Eine Website mit mindestens einem Binding (IP + Port + Hostname) und einem physischen Pfad |
| Application Pool | Isolierter W3WP-Prozess, der eine oder mehrere Apps ausführt. Hängt ein Pool, hängt die App – andere Pools laufen weiter |
| Binding | Kombination aus Protokoll (http/https), IP-Adresse, Port und optionalem Host-Header |
| Virtual Directory | Ein Unterordner in einer Site, der auf einen anderen physischen Pfad zeigt |
| Handler Mapping | Legt fest, welche Dateitypen IIS selbst verarbeitet (.aspx, .php, .html) und welche er an externe Prozesse weiterleitet |
Wie ein Request läuft:
Browser → TCP-Port 80/443 → http.sys (Kernel-Mode) → W3SVC → Application Pool (W3WP.exe) → Handler → Response
Wichtig: http.sys ist der Kernel-Treiber, der den Port hält. Deshalb können mehrere Websites auf Port 80 laufen, solange sie unterschiedliche Host-Header haben – http.sys routet vorher nach Host-Header.
Erste Website erstellen
Schritt 1 – Verzeichnis und Inhalt vorbereiten
# Webroot anlegen
New-Item -Path "C:\inetpub\intranet.firma.ch" -ItemType Directory
# Test-Startseite erstellen
Set-Content -Path "C:\inetpub\intranet.firma.ch\index.html" -Value "<h1>Intranet Firma</h1>"
# NTFS-Berechtigungen: IIS_IUSRS muss lesen dürfen
icacls "C:\inetpub\intranet.firma.ch" /grant "IIS_IUSRS:(OI)(CI)R" /T
Schritt 2 – Application Pool erstellen
# Neuen Pool mit .NET CLR Version 4.0
New-WebAppPool -Name "Intranet-Pool"
# .NET-Version setzen (v4.0 = .NET Framework 4.x, "No Managed Code" für reine Static Sites oder .NET Core)
Set-ItemProperty "IIS:\AppPools\Intranet-Pool" -Name managedRuntimeVersion -Value "v4.0"
# Identität setzen (ApplicationPoolIdentity = sicherste Option; alternativ ein Dienstkonto)
Set-ItemProperty "IIS:\AppPools\Intranet-Pool" -Name processModel.identityType -Value 4
Schritt 3 – Site erstellen
# Site erstellen (HTTP auf Port 80 mit Host-Header)
New-Website -Name "Intranet" `
-Port 80 `
-HostHeader "intranet.firma.ch" `
-PhysicalPath "C:\inetpub\intranet.firma.ch" `
-ApplicationPool "Intranet-Pool"
# Site starten
Start-Website -Name "Intranet"
# Prüfen
Get-Website -Name "Intranet"
Schritt 4 – HTTPS-Binding ergänzen
# Bestehendes Zertifikat finden (z.B. nach Subject-Name)
$cert = Get-ChildItem -Path Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*intranet.firma.ch*" } |
Select-Object -First 1
Write-Host "Thumbprint: $($cert.Thumbprint)"
# HTTPS-Binding hinzufügen
New-WebBinding -Name "Intranet" -Protocol "https" -Port 443 -HostHeader "intranet.firma.ch" -SslFlags 1
# Zertifikat ans Binding knüpfen (SNI = SslFlags 1)
$binding = Get-WebBinding -Name "Intranet" -Protocol "https"
$binding.AddSslCertificate($cert.Thumbprint, "My")
Application Pools richtig konfigurieren
Application Pools sind das wichtigste Isolations-Werkzeug in IIS. Jeder Pool läuft als eigener W3WP.exe-Prozess.
Wichtige Pool-Einstellungen:
# Prozess-Identität auf ein AD-Dienstkonto setzen
Set-ItemProperty "IIS:\AppPools\Intranet-Pool" `
-Name processModel `
-Value @{userName="FIRMA\svc-intranet"; password="Passwort123!"; identityType="SpecificUser"}
# Automatischer Neustart bei Speicherproblemen (300 MB)
Set-ItemProperty "IIS:\AppPools\Intranet-Pool" `
-Name recycling.periodicRestart.privateMemory -Value 307200
# Idle-Timeout erhöhen (Standard: 20 Min – App wird nach Inaktivität beendet)
Set-ItemProperty "IIS:\AppPools\Intranet-Pool" `
-Name processModel.idleTimeout -Value "00:30:00"
# 32-Bit aktivieren (für alte 32-Bit-DLLs)
Set-ItemProperty "IIS:\AppPools\Intranet-Pool" `
-Name enable32BitAppOnWin64 -Value $true
Pool manuell recyclen (wenn die App hängt):
Restart-WebAppPool -Name "Intranet-Pool"
Warum getrennte Pools?
Wenn App-A einen Memory Leak hat und den Pool zum Absturz bringt, läuft App-B in ihrem eigenen Pool weiter. Faustregel: Eine App = ein Pool.
web.config – Konfiguration auf Dateiebene
Die web.config im Webroot-Verzeichnis steuert das Verhalten einer einzelnen Site oder App. Sie wird von IIS automatisch geladen und kann Einstellungen aus der ApplicationHost.config überschreiben.
Typische web.config für statische Site mit Redirect:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<!-- HTTP auf HTTPS umleiten -->
<rewrite>
<rules>
<rule name="HTTP zu HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
<!-- Standarddokument -->
<defaultDocument>
<files>
<add value="index.html" />
<add value="default.aspx" />
</files>
</defaultDocument>
<!-- Verzeichnislisting deaktivieren -->
<directoryBrowse enabled="false" />
<!-- Sicherheits-Header -->
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="SAMEORIGIN" />
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
IIS per PowerShell verwalten
Der IIS-Manager (inetmgr) ist gut für einzelne Anpassungen. Für Scripting und Automatisierung nutzt du das WebAdministration-Modul:
# Modul laden
Import-Module WebAdministration
# Alle Sites anzeigen
Get-Website
# Alle Application Pools anzeigen
Get-WebAppPool
# Site stoppen / starten
Stop-Website -Name "Intranet"
Start-Website -Name "Intranet"
# Bindings einer Site anzeigen
Get-WebBinding -Name "Intranet"
# Binding entfernen
Remove-WebBinding -Name "Intranet" -Protocol "http" -Port 80
# Physischen Pfad einer Site ändern
Set-ItemProperty "IIS:\Sites\Intranet" -Name physicalPath -Value "C:\inetpub\intranet-v2"
# Site-Zustand (Running / Stopped)
(Get-Website -Name "Intranet").State
# Alle gestoppten Sites finden
Get-Website | Where-Object { $_.State -eq "Stopped" }
Logs analysieren
IIS-Logs liegen standardmässig hier:
C:\inetpub\logs\LogFiles\W3SVC1\ # Site ID 1
C:\inetpub\logs\LogFiles\W3SVC2\ # Site ID 2
Das Format ist W3C Extended Log Format – ein Leerzeichen-getrenntes Textformat:
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2026-06-23 08:15:42 192.168.10.5 GET /api/status - 443 - 192.168.10.20 Mozilla/5.0... 200 0 0 45
Wichtige HTTP-Statuscodes in IIS-Logs:
| Status | Bedeutung |
|---|---|
| 200 | OK |
| 301 / 302 | Redirect (permanent / temporär) |
| 401 | Nicht autorisiert (Authentifizierung fehlt) |
| 403 | Verboten (Zugriff verweigert, z. B. fehlende NTFS-Rechte) |
| 404 | Nicht gefunden |
| 500 | Interner Serverfehler (App-Fehler) |
| 503 | Service Unavailable (Application Pool gestoppt oder überlastet) |
Logs per PowerShell auswerten:
# Alle 500er der letzten Stunde
$logPath = "C:\inetpub\logs\LogFiles\W3SVC1\"
Get-Content "$logPath\u_ex$(Get-Date -Format 'yyMMdd').log" |
Where-Object { $_ -match " 500 " } |
Select-Object -Last 20
# Anzahl Requests pro Stunde zählen (quick & dirty)
Get-Content "$logPath\u_ex$(Get-Date -Format 'yyMMdd').log" |
Where-Object { $_ -notmatch "^#" } |
ForEach-Object { $_.Split(" ")[1].Substring(0,2) } |
Group-Object | Sort-Object Name
Tipp: Für ernsthafte Log-Analyse lohnt sich Log Parser Studio von Microsoft – kostenlos, SQL-ähnliche Abfragesprache auf IIS-Logs.
Troubleshooting – typische Probleme
503 Service Unavailable
Der Application Pool ist gestoppt oder wurde durch einen Fehler beendet.
# Pool-Status prüfen
Get-WebAppPool | Select-Object Name, State
# Pool manuell starten
Start-WebAppPool -Name "Intranet-Pool"
# Windows Ereignisanzeige auf Pool-Crashes prüfen
Get-EventLog -LogName System -Source "WAS" -Newest 20
Typische Ursachen: Memory Limit erreicht, Absturz des Worker-Prozesses, falsche Pool-Identität.
401 Unauthorized – Endlosschleife
Passiert, wenn Windows-Authentifizierung aktiviert ist, aber der Browser kein NTLM/Kerberos-Ticket schickt (z.B. bei falscher SPN-Konfiguration oder externem Zugriff).
# Authentifizierungsmodule einer Site prüfen
Get-WebConfiguration -Filter "system.webServer/security/authentication/*" -Location "Intranet" |
Select-Object PSPath, enabled
500.19 – web.config nicht lesbar
Fehler in der web.config-Syntax oder fehlende Berechtigungen auf die Datei.
# Direkter Hinweis auf Zeile und Fehler im IIS-Manager
# Oder: Syntax im Browser prüfen – IIS zeigt die fehlerhafte Zeile an
403.14 – Directory Listing nicht erlaubt
Kein Standarddokument (index.html, default.aspx) gefunden und Verzeichnislisting deaktiviert.
# Standarddokument ergänzen
Add-WebConfiguration -Filter "system.webServer/defaultDocument/files" `
-Location "Intranet" -Value @{value="app.html"}
Fehler 0x80070005 – Access Denied
Klassischer Berechtigungsfehler. Der Application Pool hat keinen Lesezugriff auf den Webroot.
# Wer ist die Pool-Identität?
(Get-ItemProperty "IIS:\AppPools\Intranet-Pool" processModel).userName
# Leer = ApplicationPoolIdentity → NTFS-Gruppe ist "IIS AppPool\Intranet-Pool"
# Berechtigung gezielt setzen
icacls "C:\inetpub\intranet.firma.ch" /grant "IIS AppPool\Intranet-Pool:(OI)(CI)R" /T
Sicherheits-Checkliste für IIS
Diese Punkte solltest du bei jeder produktiven IIS-Installation abhaken:
# 1. IIS-Version aus HTTP-Header entfernen (kein Fingerprinting)
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering" `
-PSPath "IIS:\" -Name "removeServerHeader" -Value $true
# 2. HTTP-Methoden einschränken (nur GET und POST erlauben)
# in web.config:
# <requestFiltering>
# <verbs allowUnlisted="false">
# <add verb="GET" allowed="true" />
# <add verb="POST" allowed="true" />
# </verbs>
# </requestFiltering>
# 3. Verzeichnislisting global deaktivieren
Set-WebConfigurationProperty -Filter "system.webServer/directoryBrowse" `
-PSPath "IIS:\" -Name "enabled" -Value $false
# 4. Request-Grösse begrenzen (Standard: 30 MB, für APIs kleiner setzen)
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering" `
-PSPath "IIS:\" -Name "maxAllowedContentLength" -Value 10485760 # 10 MB
# 5. Fehlerseiten ohne Details nach aussen zeigen
Set-WebConfigurationProperty -Filter "system.webServer/httpErrors" `
-PSPath "IIS:\" -Name "errorMode" -Value "DetailedLocalOnly"
Crosslinks
Thematisch passende Seiten in diesem Wiki:
- SSL/TLS-Zertifikate – Zertifikate beantragen, installieren und ans IIS-Binding knüpfen
- Windows-Firewall – Port 80 und 443 in der Windows-Firewall freigeben
- DNS-Grundlagen – Ohne korrekten DNS-Eintrag (A-Record oder CNAME) ist die Site nicht erreichbar
- PowerShell IT-Alltag – Grundlagen für die PowerShell-Befehle auf dieser Seite
Weiterlernen
- IIS-Dokumentation – Microsoft Learn (deutsch)
- IIS-Webserver Übersicht – Microsoft Learn
- Application Pools Konfiguration – Microsoft Learn
- URL Rewrite Module – iis.net
- IIS auf Windows Server einrichten – Armann Systems
- IIS als Webserver – IT-Learner.de (deutsch)
Videos
Kommentare
Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.
- Lade Kommentare …