IIS 6.0 Maintenance and Troubleshooting Guide
Critical Notice
⚠️ IIS 6.0 on Windows Server 2003 is unsupported and vulnerable to numerous security exploits. This guide is for emergency maintenance only while planning immediate migration to IIS 10 on Windows Server 2022.
Overview
Internet Information Services (IIS) 6.0 was a significant improvement over previous versions, introducing application pools and better isolation. However, it lacks modern security features and has known vulnerabilities. This guide covers essential maintenance and troubleshooting while you plan migration.
IIS 6.0 Architecture
Core Components
IIS 6.0 Architecture:
├── HTTP.sys (Kernel Mode)
│ ├── Request Queue
│ ├── Response Cache
│ └── Logging
├── W3SVC (User Mode)
│ ├── Configuration
│ ├── Process Management
│ └── Health Monitoring
├── Worker Processes (w3wp.exe)
│ ├── Application Pools
│ ├── ISAPI Extensions
│ └── ASP.NET Integration
└── IIS Admin Service
├── Metabase (MetaBase.xml)
└── Configuration Management
Essential Maintenance Tasks
1. Log Management
Configure Logging
' ConfigureIISLogging.vbs
Set objIIS = GetObject("IIS://localhost/W3SVC")
' Set log file directory
objIIS.LogFileDirectory = "D:\IISLogs"
' Configure W3C Extended Log Format
objIIS.LogType = 1 ' W3C Extended Log File Format
objIIS.LogExtFileFlags = 2199023 ' All fields
' Set log rotation
objIIS.LogFilePeriod = 1 ' Daily
objIIS.LogFileTruncateSize = 104857600 ' 100MB
objIIS.SetInfo()
WScript.Echo "IIS logging configured successfully"
Log Cleanup Script
@echo off
:: IISLogCleanup.bat - Clean old IIS logs
set LogPath=C:\WINDOWS\system32\LogFiles
set DaysToKeep=30
echo Cleaning IIS logs older than %DaysToKeep% days...
:: Clean W3SVC logs
forfiles /p "%LogPath%" /s /m *.log /d -%DaysToKeep% /c "cmd /c del @path"
:: Compress recent logs
for /f "tokens=*" %%a in ('dir /b /s "%LogPath%\*.log" ^| findstr /v ".zip"') do (
if exist "%%a" (
makecab "%%a" "%%a.zip"
del "%%a"
)
)
echo Log cleanup complete.
2. Application Pool Management
Monitor Application Pools
' MonitorAppPools.vbs
On Error Resume Next
Set objWMI = GetObject("winmgmts://./root/MicrosoftIISv2")
Set colAppPools = objWMI.ExecQuery("SELECT * FROM IIsApplicationPool")
For Each objPool in colAppPools
WScript.Echo "Application Pool: " & objPool.Name
WScript.Echo " State: " & GetPoolState(objPool.AppPoolState)
' Check for failures
Set colWorkerProcesses = objWMI.ExecQuery(_
"SELECT * FROM IIsWorkerProcess WHERE AppPoolId='" & objPool.Name & "'")
WScript.Echo " Worker Processes: " & colWorkerProcesses.Count
WScript.Echo ""
Next
Function GetPoolState(state)
Select Case state
Case 2 : GetPoolState = "Started"
Case 4 : GetPoolState = "Stopped"
Case Else : GetPoolState = "Unknown"
End Select
End Function
Recycle Application Pools
@echo off
:: RecycleAppPools.bat - Scheduled application pool recycling
echo Recycling application pools...
:: List all application pools
cscript %SystemRoot%\system32\iisapp.vbs /a > appools.txt
:: Recycle each pool
for /f "tokens=2" %%a in ('findstr /i "W3WP.exe" appools.txt') do (
echo Recycling pool: %%a
cscript %SystemRoot%\system32\iisapp.vbs /r /a %%a
timeout /t 5 >nul
)
del appools.txt
echo Application pool recycling complete.
3. Performance Monitoring
Key Performance Counters
# IISPerfMon.ps1 - Monitor IIS performance
$counters = @(
"\Web Service(_Total)\Bytes Total/sec",
"\Web Service(_Total)\Current Connections",
"\Web Service(_Total)\Connection Attempts/sec",
"\ASP.NET\Requests Queued",
"\ASP.NET\Requests Current",
"\Process(w3wp*)\% Processor Time",
"\Process(w3wp*)\Private Bytes",
"\HTTP Service Request Queues(_Total)\CurrentQueueSize"
)
while($true) {
Clear-Host
Write-Host "IIS 6.0 Performance Monitor - $(Get-Date)" -ForegroundColor Green
Write-Host "="*50
foreach($counter in $counters) {
try {
$value = (Get-Counter $counter -ErrorAction SilentlyContinue).CounterSamples[0].CookedValue
Write-Host "$counter : $([math]::Round($value, 2))"
} catch {
Write-Host "$counter : N/A" -ForegroundColor Red
}
}
Start-Sleep -Seconds 5
}
Troubleshooting Common Issues
1. HTTP Error Codes
Diagnose HTTP Errors
' DiagnoseHTTPErrors.vbs
Dim objFSO, objFile, strLine
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Parse HTTPERR logs
strLogPath = "C:\WINDOWS\system32\LogFiles\HTTPERR\"
Set objFolder = objFSO.GetFolder(strLogPath)
For Each objFile in objFolder.Files
If Right(objFile.Name, 4) = ".log" Then
Set objTextFile = objFSO.OpenTextFile(objFile.Path, 1)
Do Until objTextFile.AtEndOfStream
strLine = objTextFile.ReadLine
' Check for common errors
If InStr(strLine, "Connection_Abandoned") > 0 Then
WScript.Echo "Connection Abandoned: " & strLine
ElseIf InStr(strLine, "Timer_ConnectionIdle") > 0 Then
WScript.Echo "Idle Timeout: " & strLine
ElseIf InStr(strLine, "400") > 0 Then
WScript.Echo "Bad Request: " & strLine
End If
Loop
objTextFile.Close
End If
Next
2. Application Pool Failures
Rapid Fail Protection
<!-- Add to MetaBase.xml for specific application pool -->
<IIsApplicationPool Location="/LM/W3SVC/AppPools/DefaultAppPool"
RapidFailProtection="TRUE"
RapidFailProtectionInterval="5"
RapidFailProtectionMaxCrashes="5"
AutoShutdownAppPoolExe="cscript.exe C:\Scripts\NotifyPoolFailure.vbs"
>
</IIsApplicationPool>
Monitor Worker Process Health
@echo off
:: CheckW3WP.bat - Monitor worker process health
:loop
cls
echo IIS Worker Process Monitor
echo ==========================
echo.
:: List all worker processes
tasklist /fi "imagename eq w3wp.exe" /fo table
:: Check memory usage
for /f "tokens=2,6" %%a in ('tasklist /fi "imagename eq w3wp.exe" /fo list ^| findstr "PID Memory"') do (
if %%b GTR 524288 (
echo WARNING: Process %%a using excessive memory: %%b K
)
)
timeout /t 10 >nul
goto loop
3. SSL/TLS Configuration
Secure SSL Settings
@echo off
:: SecureSSL.bat - Configure secure SSL/TLS settings
echo Disabling weak protocols...
:: Disable SSL 2.0
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v Enabled /t REG_DWORD /d 0 /f
:: Disable SSL 3.0
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" /v Enabled /t REG_DWORD /d 0 /f
:: Enable TLS 1.0 (highest supported on 2003)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" /v Enabled /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" /v Enabled /t REG_DWORD /d 1 /f
echo SSL/TLS configuration complete. Restart required.
4. Metabase Corruption
Backup Metabase
' BackupMetabase.vbs
Dim objComputer, strBackupName
Set objComputer = GetObject("IIS://localhost")
strBackupName = "MetabaseBackup_" & Year(Now) & Month(Now) & Day(Now)
' Create backup with password
objComputer.Backup strBackupName, MD_BACKUP_SAVE_FIRST, "BackupPassword123"
WScript.Echo "Metabase backed up as: " & strBackupName
Restore Metabase
@echo off
:: RestoreMetabase.bat
echo WARNING: This will restore IIS configuration!
pause
:: Stop IIS services
net stop w3svc /y
net stop iisadmin /y
:: Restore from backup
cd %windir%\system32\inetsrv
cscript iisback.vbs /restore /b MetabaseBackup_20240115 /v 1
:: Restart IIS
net start iisadmin
net start w3svc
echo Metabase restore complete.
Security Hardening
1. Remove Default Content
@echo off
:: RemoveIISDefaults.bat
echo Removing IIS default content...
:: Remove sample applications
rd /s /q "C:\Inetpub\iissamples"
rd /s /q "C:\Inetpub\AdminScripts"
rd /s /q "C:\WINDOWS\Help\iisHelp"
:: Remove default documents
del /q "C:\Inetpub\wwwroot\iisstart.htm"
del /q "C:\Inetpub\wwwroot\welcome.png"
:: Disable directory browsing
cscript %SystemRoot%\system32\adsutil.vbs SET W3SVC/DirectoryBrowsing FALSE
echo Default content removed.
2. Configure Request Filtering
<!-- Add URLScan configuration - urlscan.ini -->
[Options]
UseAllowVerbs=1
UseAllowExtensions=0
NormalizeUrlBeforeScan=1
VerifyNormalization=1
AllowHighBitCharacters=0
AllowDotInPath=0
RemoveServerHeader=1
[AllowVerbs]
GET
POST
HEAD
[DenyExtensions]
.exe
.bat
.cmd
.com
.htw
.ida
.idq
.htr
.idc
.shtm
.shtml
.stm
.printer
.ini
.log
.pol
.dat
[DenyHeaders]
Transfer-Encoding:
3. Custom Error Pages
' SetCustomErrors.vbs
Set objIIS = GetObject("IIS://localhost/W3SVC/1/Root")
' Set custom error pages
objIIS.HttpErrors = "404,0,FILE,C:\Inetpub\errors\404.htm" & _
",500,0,FILE,C:\Inetpub\errors\500.htm" & _
",403,0,FILE,C:\Inetpub\errors\403.htm"
objIIS.SetInfo()
WScript.Echo "Custom error pages configured"
Performance Optimization
1. HTTP Compression
' EnableCompression.vbs
Set objIIS = GetObject("IIS://localhost/W3SVC/Filters/Compression/gzip")
' Enable GZIP compression
objIIS.HcDoStaticCompression = TRUE
objIIS.HcDoDynamicCompression = TRUE
objIIS.HcFileExtensions = "htm html txt css js"
objIIS.HcScriptFileExtensions = "asp aspx"
objIIS.HcCompressionLevel = 9
objIIS.SetInfo()
WScript.Echo "HTTP compression enabled"
2. Connection Limits
@echo off
:: OptimizeConnections.bat
echo Optimizing IIS connection settings...
:: Set connection timeout (900 seconds = 15 minutes)
cscript %SystemRoot%\system32\adsutil.vbs SET W3SVC/ConnectionTimeout 900
:: Set maximum connections
cscript %SystemRoot%\system32\adsutil.vbs SET W3SVC/MaxConnections 1000
:: Enable HTTP keep-alives
cscript %SystemRoot%\system32\adsutil.vbs SET W3SVC/AllowKeepAlive TRUE
echo Connection settings optimized.
3. Cache Configuration
' ConfigureCache.vbs
Set objIIS = GetObject("IIS://localhost/W3SVC")
' Configure kernel cache
objIIS.ServerCacheTime = 900 ' 15 minutes
objIIS.MaxCacheFileSize = 262144 ' 256KB
objIIS.MemCacheSize = 10 ' 10MB
' Configure ASP template cache
Set objASP = GetObject("IIS://localhost/W3SVC/1/Root")
objASP.AspScriptFileCacheSize = 500
objASP.AspMaxDiskTemplateCacheFiles = 2000
objIIS.SetInfo()
objASP.SetInfo()
WScript.Echo "Cache settings configured"
Monitoring and Alerting
1. Health Check Script
# IISHealthCheck.ps1
$smtpServer = "mail.company.com"
$from = "iismonitor@company.com"
$to = "admin@company.com"
function Test-WebSite($url) {
try {
$response = [System.Net.WebRequest]::Create($url).GetResponse()
$status = [int]$response.StatusCode
$response.Close()
return $status -eq 200
} catch {
return $false
}
}
# Check critical sites
$sites = @(
"http://localhost/",
"https://localhost/secure/"
)
$failures = @()
foreach($site in $sites) {
if(-not (Test-WebSite $site)) {
$failures += $site
}
}
if($failures.Count -gt 0) {
$body = "The following sites are not responding:`n`n"
$body += $failures -join "`n"
Send-MailMessage -SmtpServer $smtpServer -From $from -To $to `
-Subject "IIS Health Check Failed" -Body $body
}
2. Performance Baseline
@echo off
:: CreatePerfBaseline.bat
echo Creating IIS performance baseline...
:: Capture performance data for 1 hour
logman create counter IISBaseline -f bin -max 100 -c "\Web Service(_Total)\*" "\ASP.NET\*" "\Process(w3wp*)\*" -si 00:00:15
logman start IISBaseline
timeout /t 3600
logman stop IISBaseline
echo Performance baseline created.
Migration Preparation
1. Export Configuration
@echo off
:: ExportIISConfig.bat
set ExportPath=C:\IISMigration
mkdir %ExportPath% 2>nul
echo Exporting IIS configuration...
:: Export metabase
cscript %SystemRoot%\system32\iisback.vbs /backup /b MigrationBackup
:: Export application pools
cscript %SystemRoot%\system32\iiscnfg.vbs /export /f %ExportPath%\AppPools.xml /sp /lm/w3svc/apppools
:: Export websites
cscript %SystemRoot%\system32\iiscnfg.vbs /export /f %ExportPath%\Sites.xml /sp /lm/w3svc/1
:: Copy website content
echo Copying website files...
xcopy C:\Inetpub\wwwroot\*.* %ExportPath%\wwwroot\ /E /H /Y
echo Export complete. Files saved to %ExportPath%
2. Document Dependencies
' DocumentIIS.vbs - Create migration documentation
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("IIS_Documentation.txt", True)
objFile.WriteLine "IIS 6.0 Configuration Documentation"
objFile.WriteLine "Generated: " & Now
objFile.WriteLine String(50, "=")
' Document websites
Set objIIS = GetObject("IIS://localhost/W3SVC")
For Each objSite In objIIS
If objSite.Class = "IIsWebServer" Then
objFile.WriteLine vbCrLf & "Website: " & objSite.ServerComment
objFile.WriteLine " ID: " & objSite.Name
objFile.WriteLine " Bindings: " & objSite.ServerBindings
objFile.WriteLine " Path: " & objSite.Path
objFile.WriteLine " App Pool: " & objSite.AppPoolId
End If
Next
objFile.Close
WScript.Echo "Documentation created: IIS_Documentation.txt"
Conclusion
While this guide helps maintain IIS 6.0 on Windows Server 2003, remember that this configuration is fundamentally insecure and unsupported. Use these procedures only as temporary measures while actively migrating to IIS 10 on Windows Server 2022.
Emergency Support
- Tyler on Tech Louisville: (202) 948-8888
- 24/7 IIS Support: Available
- Email: iis-support@tylerontechlouisville.com
Last Updated: January 2024
Author: Tyler Maginnis, Tyler on Tech Louisville