Start typing to search across invoices, services, domains, tickets, and more...
If you prefer Windows or need to run ASP.NET applications, hosting a website with IIS on Windows Server is the natural choice. Using Windows Server 2016/2019/2022, this guide shows how to install IIS with PowerShell, bind a site to a specific IP and host header (very handy on multi-IP site-cluster servers), get a free auto-renewing SSL certificate with win-acme, and run PHP through IIS FastCGI.
Run the commands below in an elevated PowerShell. IIS and its management console are installed within a few minutes. If you plan to run PHP, add the CGI feature (it includes FastCGI) at the same time. Browse to the server IP afterwards: the IIS welcome page means it worked.
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
# Optional: CGI/FastCGI support (needed for PHP)
Install-WindowsFeature -Name Web-CGI
Get-WindowsFeature Web-Server, Web-CGIAn IIS binding is made of IP address + port + host header. The example below creates site1 that answers www.example.com only on 203.0.113.11 and adds the bare domain as a second host header. Replace the IP and domain with your own and point the domain's A record to that IP first.
Import-Module WebAdministration
New-Item -ItemType Directory -Path C:\inetpub\site1 -Force
Set-Content -Path C:\inetpub\site1\index.html -Value "site1 OK"
New-Website -Name "site1" -PhysicalPath "C:\inetpub\site1" -IPAddress "203.0.113.11" -Port 80 -HostHeader "www.example.com"
New-WebBinding -Name "site1" -IPAddress "203.0.113.11" -Port 80 -HostHeader "example.com"
Get-WebBinding -Name "site1"On IMIDC multi-IP and site-cluster servers a common requirement is one dedicated IP per website. First add all IPs to the network adapter (see our "add IP addresses on Windows" guide), then bind each site to its own IP. Without a host header, that site answers every domain pointed at the IP. Stop the Default Web Site so its "All Unassigned:80" binding does not steal requests.
# One site per IP, no host header (answers any domain pointed at that IP)
New-Website -Name "site2" -PhysicalPath "C:\inetpub\site2" -IPAddress "203.0.113.12" -Port 80
New-Website -Name "site3" -PhysicalPath "C:\inetpub\site3" -IPAddress "203.0.113.13" -Port 80
# Stop the Default Web Site so it does not catch *:80
Stop-Website -Name "Default Web Site"
Set-ItemProperty "IIS:\Sites\Default Web Site" -Name serverAutoStart -Value $falsewin-acme (wacs.exe) is a widely used Let's Encrypt client for Windows. It detects IIS sites, completes validation, installs the certificate, adds the 443 binding and creates a renewal task. Download the x64 zip from the official win-acme website or its GitHub releases page, extract it to C:\tools\win-acme and run it. Choose to create a certificate with default settings, then select your IIS site and domains.
cd C:\tools\win-acme
.\wacs.exe
# Check the renewal task created by win-acme
Get-ScheduledTask | Where-Object TaskName -like "win-acme*"Before requesting a certificate make sure the domain resolves to the IP bound to the site, port 80 is reachable from the internet (HTTP validation needs it) and the site bindings contain every host name you want on the certificate.
Download the NTS (Non Thread Safe) x64 zip for your PHP version from the official PHP for Windows site, extract it to C:\PHP, install the matching Visual C++ Redistributable and copy php.ini-production to php.ini. Then register the FastCGI application, map *.php to it and add index.php as a default document with appcmd:
$appcmd = "$env:windir\System32\inetsrv\appcmd.exe"
& $appcmd set config /section:system.webServer/fastCgi /+"[fullPath='C:\PHP\php-cgi.exe']"
& $appcmd set config /section:system.webServer/handlers /+"[name='PHP_via_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='C:\PHP\php-cgi.exe',resourceType='Either']"
& $appcmd set config /section:defaultDocument /+"files.[value='index.php']"
Set-Content -Path C:\inetpub\site1\info.php -Value "<?php phpinfo();"
iisresetOpen http://your-domain/info.php; a PHP information page means PHP works. Delete info.php after testing so you do not leak server details.
Another site already uses the same IP + port + host header, most often the Default Web Site. Stop it or change its binding and start your site again.
Check that the A record points to the right IP, that port 80 is reachable from outside and that no CDN or redirect rule blocks the /.well-known/acme-challenge/ path.
Choose Windows + IIS for ASP.NET and MSSQL. For PHP/MySQL sites, Linux with aaPanel/BaoTa is usually lighter; see our BaoTa installation guide.
Still stuck after following these steps? Open a support ticket and the IMIDC 24/7 technical team will help. Please include the server IP, OS version, the commands you ran and a screenshot of the error so we can pinpoint the issue faster.