Internet Information Services (IIS) with PHP and MySQL creates a powerful web hosting stack on Windows Server. This guide covers installing and configuring IIS, PHP via FastCGI, MySQL/MariaDB, and deploying PHP applications like WordPress on your Windows Server VPS.
Install IIS Web Server
# Install IIS with common features
Install-WindowsFeature -Name Web-Server, Web-Common-Http, Web-Static-Content, `
Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Http-Redirect, `
Web-App-Dev, Web-CGI, Web-ISAPI-Ext, Web-ISAPI-Filter, `
Web-Health, Web-Http-Logging, Web-Log-Libraries, Web-Request-Monitor, `
Web-Security, Web-Filtering, Web-Basic-Auth, `
Web-Performance, Web-Stat-Compression, Web-Dyn-Compression, `
Web-Mgmt-Tools, Web-Mgmt-Console `
-IncludeManagementTools
# Verify IIS is running
Get-Service W3SVC
Start-Process "http://localhost"
Install PHP
# Download PHP for Windows (Non Thread Safe for IIS FastCGI)
$phpVersion = "8.3.14"
$phpUrl = "https://windows.php.net/downloads/releases/php-$phpVersion-nts-Win32-vs16-x64.zip"
Invoke-WebRequest -Uri $phpUrl -OutFile "C:\temp\php.zip"
# Extract PHP
Expand-Archive "C:\temp\php.zip" -DestinationPath "C:\PHP" -Force
# Configure php.ini
Copy-Item "C:\PHP\php.ini-production" "C:\PHP\php.ini"
# Edit php.ini with common settings
$phpIni = Get-Content "C:\PHP\php.ini"
$phpIni = $phpIni -replace ";extension_dir = ""ext""", "extension_dir = ""C:\PHP\ext"""
$phpIni = $phpIni -replace ";extension=curl", "extension=curl"
$phpIni = $phpIni -replace ";extension=gd", "extension=gd"
$phpIni = $phpIni -replace ";extension=mbstring", "extension=mbstring"
$phpIni = $phpIni -replace ";extension=mysqli", "extension=mysqli"
$phpIni = $phpIni -replace ";extension=pdo_mysql", "extension=pdo_mysql"
$phpIni = $phpIni -replace ";extension=openssl", "extension=openssl"
$phpIni = $phpIni -replace ";extension=fileinfo", "extension=fileinfo"
$phpIni = $phpIni -replace ";extension=intl", "extension=intl"
$phpIni = $phpIni -replace "upload_max_filesize = 2M", "upload_max_filesize = 64M"
$phpIni = $phpIni -replace "post_max_size = 8M", "post_max_size = 64M"
$phpIni = $phpIni -replace "memory_limit = 128M", "memory_limit = 256M"
$phpIni = $phpIni -replace ";date.timezone =", "date.timezone = America/New_York"
$phpIni | Set-Content "C:\PHP\php.ini"
# Add PHP to system PATH
$path = [Environment]::GetEnvironmentVariable("Path", "Machine")
[Environment]::SetEnvironmentVariable("Path", "$path;C:\PHP", "Machine")
# Verify PHP
C:\PHP\php.exe -v
C:\PHP\php.exe -m
Configure IIS FastCGI for PHP
# Register PHP with IIS via FastCGI
Import-Module WebAdministration
# Add FastCGI handler
Add-WebConfigurationProperty -PSPath "IIS:\" `
-Filter "system.webServer/fastCgi" `
-Name "." `
-Value @{
fullPath = "C:\PHP\php-cgi.exe"
maxInstances = 10
idleTimeout = 300
activityTimeout = 600
requestTimeout = 600
}
# Add handler mapping
New-WebHandler -Name "PHP-FastCGI" `
-Path "*.php" `
-Verb "*" `
-Modules "FastCgiModule" `
-ScriptProcessor "C:\PHP\php-cgi.exe" `
-ResourceType File
# Set default document
Add-WebConfigurationProperty -PSPath "IIS:\Sites\Default Web Site" `
-Filter "system.webServer/defaultDocument/files" `
-Name "." `
-Value @{ value = "index.php" }
# Test with phpinfo
Set-Content "C:\inetpub\wwwroot\phpinfo.php" "<?php phpinfo(); ?>"
Install MySQL
# Download MySQL Installer
$mysqlUrl = "https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.36-winx64.zip"
Invoke-WebRequest -Uri $mysqlUrl -OutFile "C:\temp\mysql.zip"
# Extract
Expand-Archive "C:\temp\mysql.zip" -DestinationPath "C:\MySQL" -Force
# Initialize MySQL
C:\MySQL\bin\mysqld.exe --initialize-insecure --console
C:\MySQL\bin\mysqld.exe --install
Start-Service MySQL
# Set root password
C:\MySQL\bin\mysql.exe -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'SecureMySQL2026!';"
# Create application database
C:\MySQL\bin\mysql.exe -u root -p'SecureMySQL2026!' -e "
CREATE DATABASE wordpress;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'WpP@ss2026!';
GRANT ALL ON wordpress.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
"
Deploy WordPress
# Download WordPress
Invoke-WebRequest -Uri "https://wordpress.org/latest.zip" -OutFile "C:\temp\wordpress.zip"
Expand-Archive "C:\temp\wordpress.zip" -DestinationPath "C:\inetpub\wwwroot" -Force
# Create IIS site
New-Website -Name "WordPress" `
-PhysicalPath "C:\inetpub\wwwroot\wordpress" `
-HostHeader "www.example.com" `
-Port 80
# Set folder permissions
icacls "C:\inetpub\wwwroot\wordpress" /grant "IIS_IUSRS:(OI)(CI)M" /T
# Install URL Rewrite module for WordPress permalinks
# Download from: https://www.iis.net/downloads/microsoft/url-rewrite
# Create web.config for WordPress
$webConfig = @'
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WordPress" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
'@
Set-Content "C:\inetpub\wwwroot\wordpress\web.config" $webConfig
SSL Configuration
# Install win-acme for Let's Encrypt
Invoke-WebRequest -Uri "https://github.com/win-acme/win-acme/releases/download/v2.2.9.1701/win-acme.v2.2.9.1701.x64.pluggable.zip" `
-OutFile "C:\temp\win-acme.zip"
Expand-Archive "C:\temp\win-acme.zip" -DestinationPath "C:\win-acme"
# Request certificate
C:\win-acme\wacs.exe --target iis --siteid 2 --installation iis --emailaddress admin@example.com --accepttos
Best Practices
- Use Non-Thread-Safe PHP with FastCGI on IIS for best performance
- Enable OPcache in php.ini for significant PHP performance improvement
- Set appropriate PHP process limits in FastCGI settings based on available RAM
- Use URL Rewrite module for clean URLs in PHP applications
- Configure request filtering to block malicious requests
- Enable dynamic compression for PHP responses
- Use win-acme for automatic Let's Encrypt SSL certificate management