Install IIS and Serve a Static Site with HTTPS
Install IIS on Windows Server 2022, publish a static site, bind HTTPS with a certificate, and redirect HTTP so the origin is not leftover plaintext.
Netbay Engineering
Netbay Engineering
On this page
IIS is the reason a lot of teams rent a Windows VPS. You do not need Visual Studio on the server, and you do not need the full application-server pile to ship a static site or a small ASP.NET app. Install the Web Server role, put files on High-Speed SSD, bind a hostname, and put TLS on 443. HTTP on 80 should only exist to redirect.
This walkthrough is Server 2022, one public IPv4, one site. It is enough for a brochure site, a status page, or the static front of a .NET app you will add later. It is not a farm, not ARR, and not a CMS marketplace.
Install only the IIS features you will use
Desktop Experience makes Server Manager tempting. Use PowerShell anyway so the role list is repeatable. Web-Server, Common HTTP, Security, and Performance cover static files, default documents, compression, and request filtering. Skip FTP. Skip CGI until an app needs it. Management Tools are worth it if you want IIS Manager later.
Install-WindowsFeature -Name Web-Server, Web-Common-Http, Web-Static-Content, Web-Default-Doc, Web-Dir-Browse, Web-Http-Errors, Web-Http-Redirect, Web-Security, Web-Filtering, Web-Stat-Compression, Web-Mgmt-Console -IncludeManagementTools
Get-WindowsFeature Web-* | Where-Object Installed | Select-Object Name, DisplayName
New-Item -ItemType Directory -Path 'C:\inetpub\wwwroot\site' -Force
Set-Content -Path 'C:\inetpub\wwwroot\site\index.html' -Value '<!doctype html><html><body><h1>ok</h1></body></html>'
New-Website -Name 'site' -PhysicalPath 'C:\inetpub\wwwroot\site' -Port 80 -HostHeader 'www.example.com' -Force
Stop-Website -Name 'Default Web Site'
Get-Website | Format-Table Name, State, PhysicalPath, BindingsReplace www.example.com with the name you will put in DNS. Point an A record at the VPS public IPv4. Keep Default Web Site stopped so you do not serve the IIS splash page on a leftover binding. Directory browsing should stay off in production; the feature is installed so you can toggle it, not so the world can list C:\inetpub.
Put a certificate on 443
For a lab, a self-signed cert lets you test the binding. Browsers will warn. For production, use a publicly trusted certificate. win-acme (wacs.exe) is the usual Let's Encrypt client on Windows and talks HTTP-01 against port 80. Whatever CA you use, the IIS binding must attach the cert's thumbprint to 443 and the same host header.
$cert = New-SelfSignedCertificate -DnsName 'www.example.com' -CertStoreLocation 'Cert:\LocalMachine\My'
New-WebBinding -Name 'site' -Protocol https -Port 443 -HostHeader 'www.example.com' -SslFlags 1
$guid = [guid]::NewGuid().ToString('B')
netsh http add sslcert hostnameport=www.example.com:443 certhash=$cert.Thumbprint appid=$guid certstorename=MY
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/httpRedirect' -Name enabled -Value $false
New-Item -ItemType Directory -Path 'C:\inetpub\wwwroot\site' -Force | Out-Null
$webConfig = @'
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="http to https" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
'@
Set-Content -Path 'C:\inetpub\wwwroot\site\web.config' -Value $webConfig
Install-WindowsFeature Web-Http-Redirect | Out-NullURL Rewrite is a separate IIS module. If the rewrite section is ignored, install the URL Rewrite module from Microsoft, or use an httpRedirect that only kicks in on HTTP. The point is that port 80 must not serve the real site as plaintext once 443 works. Confirm with curl.exe -I http://www.example.com/ and look for 301 to https.
The @{ } and $webConfig here-string use @' '@ so nothing expands. Do not paste a C# interpolated string into this file later. Thumbprints go into netsh as hex with no spaces.
Firewall, files, and what to check
Open 80 and 443 on the Public profile. Do not open 21, 990, or 8080 "in case". The site files should be readable by IIS_IUSRS and the app-pool identity, not writable by Everyone. After the first request, C:\inetpub\logs\LogFiles will grow; rotate or trim on a schedule so a quiet static site does not fill the volume.
App pools: one pool per site even for static content. The default Classic pipeline is the wrong choice for modern ASP.NET; Integrated is the default on 2022 and you should leave it. For static files, the pool can be idle-timeout friendly. For a .NET app you will convert this site into later, disable idle timeout so the first request after a quiet night is not a cold start.
Test from a machine that is not the VPS. Local curl to 127.0.0.1 bypasses host-header and firewall mistakes you still have. Use the public name. If TLS fails, netsh http show sslcert and the IIS binding list must agree on the thumbprint.
Takeaway
Install a tight IIS feature set, bind a host header, attach a certificate to 443, and make 80 a redirect. Keep Default Web Site stopped and the filesystem boring. You can stand up Windows Server 2022 on Netbay in Lucknow, point DNS at the public IPv4, and complete this origin setup on High-Speed SSD from netbayhosts.in.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance