{"id":736,"date":"2026-09-11T23:21:28","date_gmt":"2026-09-11T23:21:28","guid":{"rendered":"https:\/\/windows-vps.org\/blog\/?p=736"},"modified":"2026-09-11T23:21:28","modified_gmt":"2026-09-11T23:21:28","slug":"install-configure-iis-remote-windows-server","status":"publish","type":"post","link":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/","title":{"rendered":"How to Install and Configure IIS on a Remote Windows Server"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">IIS is the one Windows Server role almost every hosted VM ends up running, and it is also the role people install by clicking through Server Manager and then never configure properly. This guide installs IIS from PowerShell, creates a dedicated application pool, publishes a site on a host header, opens the firewall correctly, and gets HTTPS working \u2014 the full path from a bare remote server to a live site.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>A remote Windows Server (2019, 2022, or 2025) with administrator RDP access \u2014 see <a href=\"https:\/\/windows-vps.org\/\">windows-vps.org<\/a> if you still need a plan.<\/li><li>PowerShell 5.1 or 7, running as Administrator.<\/li><li>A DNS record you can edit, if you want a real hostname.<\/li><li>Roughly 1.5 GB of free system disk for the role plus its logs.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1 \u2014 Install the Web Server Role<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Full IIS with management tools, .NET, and common extras\nInstall-WindowsFeature -Name Web-Server, Web-Mgmt-Console, Web-Asp-Net45, Web-Net-Ext45, `\n    Web-Http-Logging, Web-Stat-Compression, Web-Dyn-Compression, Web-Filtering, `\n    Web-Basic-Auth, Web-Windows-Auth, Web-Mgmt-Service, Web-Request-Monitor `\n    -IncludeManagementTools\n\n# Confirm\nGet-WindowsFeature Web-Server | Select-Object Name, InstallState<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Windows 10\/11 the equivalent is the DISM feature name:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-WebServer, IIS-ManagementConsole -All<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2 \u2014 Verify the Default Site Answers<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>Get-Service W3SVC | Select-Object Name, Status, StartType\nInvoke-WebRequest http:\/\/localhost -UseBasicParsing | Select-Object StatusCode\n(Get-Website -Name 'Default Web Site').State<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A 200 response with the blue IIS welcome page means the service is healthy. If the service will not start, check the Windows Event Log under <code>Application<\/code> for <code>WAS<\/code> errors \u2014 a missing .NET feature is the usual culprit.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3 \u2014 Create a Dedicated Application Pool and Site<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>$site   = 'mysite.com'\n$root   = \"C:\\inetpub\\$site\"\n$pool   = \"pool-$site\"\n\nNew-Item -ItemType Directory -Path $root -Force | Out-Null\nNew-Item -ItemType Directory -Path \"$root\\logs\" -Force | Out-Null\n\n# Application pool: no managed code if the site is static\/Node\/PHP\nNew-WebAppPool -Name $pool\nSet-ItemProperty \"IIS:\\AppPools\\$pool\" -Name managedRuntimeVersion -Value 'v4.0'\nSet-ItemProperty \"IIS:\\AppPools\\$pool\" -Name processModel.idleTimeout -Value '00:00:00'   # never idle out\nSet-ItemProperty \"IIS:\\AppPools\\$pool\" -Name recycling.periodicRestart.time -Value '00:00:00'  # recycle on schedule instead\n\n# The site itself\nNew-Website -Name $site -PhysicalPath $root -ApplicationPool $pool -HostHeader $site -Port 80\n\n# A plain test page so you have something to curl\nSet-Content \"$root\\index.html\" \"&lt;h1&gt;$site is live on IIS&lt;\/h1&gt;\"\nStart-Website -Name $site\nGet-Website | Format-Table Name, State, PhysicalPath, ApplicationPool<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Two defaults are worth changing immediately. First, <code>idleTimeout<\/code> of 20 minutes unloads your app pool and makes the first request after a quiet period pay a multi-second warm-up \u2014 set it to zero. Second, the default periodic recycle every 1,740 minutes interrupts requests; schedule it during a known maintenance window using <code>recycling.periodicRestart.schedule<\/code> instead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4 \u2014 Open the Firewall Correctly<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Installing the Web-Server feature creates an inbound rule, but it is bound to the &#8220;Public&#8221; profile only in some configurations and does not cover HTTPS. Define your own rule explicitly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>New-NetFirewallRule -DisplayName 'IIS HTTP 80'  -Direction Inbound -Protocol TCP -LocalPort 80  -Action Allow -Profile Any\nNew-NetFirewallRule -DisplayName 'IIS HTTPS 443' -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow -Profile Any\n\n# Verify what is listening\nGet-NetTCPConnection -State Listen | Where-Object LocalPort -in 80,443 | Format-Table LocalAddress, LocalPort, OwningProcess\nGet-NetFirewallRule -DisplayName 'IIS*' | Format-Table DisplayName, Enabled, Direction, Action<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A common mistake is deleting the built-in rules instead of disabling them. Disable with <code>Disable-NetFirewallRule<\/code> so you can reverse the decision later.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5 \u2014 Point a Domain at It<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create an <code>A<\/code> record for <code>mysite.com<\/code> (and a <code>www<\/code> CNAME) pointing at the server&#8217;s public IP. On the server, add a second binding so both names resolve to the same site:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>New-WebBinding -Name 'mysite.com' -Protocol http -Port 80 -HostHeader 'www.mysite.com'\nGet-WebBinding -Name 'mysite.com' | Format-Table protocol, bindingInformation<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Host headers are what let one server host many sites on one IP. Without them, the second site you create will either collide on port 80 or require its own IP address. If you need to host several domains, plan the host-header table before you add bindings \u2014 retrofitting is more painful than doing it first.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6 \u2014 Fix NTFS Permissions for the App Pool Identity<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">By default an app pool runs as <code>ApplicationPoolIdentity<\/code>, a virtual account named <code>IIS AppPool\\pool-mysite.com<\/code>. Grant it read access to the content and nothing more:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>icacls \"C:\\inetpub\\mysite.com\" \/grant \"IIS AppPool\\pool-mysite.com:(OI)(CI)(RX)\" \/T\nicacls \"C:\\inetpub\\mysite.com\\logs\" \/grant \"IIS AppPool\\pool-mysite.com:(OI)(CI)(M)\" \/T\n\n# Inspect current ACLs\nGet-Acl 'C:\\inetpub\\mysite.com' | Format-List<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Never grant <code>Everyone:Full<\/code> or add the app pool to the Administrators group. If your app must write to a folder, give it Modify on that one folder only \u2014 that is the entire point of running the pool under a low-privilege identity.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7 \u2014 Add HTTPS<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Import a PFX (keystore) certificate\n$pw = ConvertTo-SecureString -String 'YourPfxPassword' -AsPlainText -Force\nImport-PfxCertificate -FilePath C:\\certs\\mysite.pfx -CertStoreLocation Cert:\\LocalMachine\\My -Password $pw\n\n# Bind it \u2014 must be SNI-enabled on modern servers\nNew-WebBinding -Name 'mysite.com' -Protocol https -Port 443 -HostHeader 'mysite.com' -SslFlags 1\nGet-Item Cert:\\LocalMachine\\My | Select-Object Subject, Thumbprint, NotAfter<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>SslFlags value<\/th><th>Meaning<\/th><th>When to use<\/th><\/tr><\/thead><tbody><tr><td>0<\/td><td>No SNI, single cert on the IP<\/td><td>Legacy clients only<\/td><\/tr><tr><td>1<\/td><td>SNI enabled<\/td><td>Multiple HTTPS sites on one IP \u2014 the normal choice<\/td><\/tr><tr><td>3<\/td><td>SNI + Central Certificate Store<\/td><td>Farm \/ many-certificate deployments<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting Reference<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Symptom<\/th><th>Cause<\/th><th>Fix<\/th><\/tr><\/thead><tbody><tr><td>HTTP 500.19<\/td><td>Config section locked or malformed web.config<\/td><td>Unlock section in <code>applicationHost.config<\/code>; validate XML<\/td><\/tr><tr><td>HTTP 403.14<\/td><td>Directory browsing disabled and no default document<\/td><td>Add a default document or publish index.html<\/td><\/tr><tr><td>HTTP 404.4 \/ 404.7<\/td><td>No route\/file, or extension not allowed<\/td><td>Check request filtering <code>fileExtensions<\/code><\/td><\/tr><tr><td>HTTP 503<\/td><td>App pool stopped or crashed repeatedly<\/td><td><code>Enable-WebAppPoolRapidFailProtection -Enable $false<\/code> to see the real error<\/td><\/tr><tr><td>Site works on localhost, not from outside<\/td><td>Firewall or host header binding<\/td><td>Re-check the rule and add the public hostname binding<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Next Steps<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable request logging and set up Failed Request Tracing for 500s.<\/li><li>Add response compression and a cache header policy for static assets.<\/li><li>Harden the server: remove unused modules, disable directory browsing, set request limits.<\/li><li>Automate the whole build as a PowerShell script you can re-run on a fresh VM.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Everything above is scriptable, which is the real advantage of a remote Windows server: the entire stack from a blank template to a TLS-terminating site is a single idempotent script. If you are sizing the machine for this workload, <a href=\"https:\/\/windows-vps.org\/\">windows-vps.org<\/a> covers what RAM and disk an IIS deployment realistically needs.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>IIS is the one Windows Server role almost every hosted VM ends up running, and it is also the role people install by clicking through Server Manager and then never configure properly. This guide installs IIS from PowerShell, creates a dedicated application pool, publishes a site on a host header, opens the firewall correctly, and &#8230; <a title=\"How to Install and Configure IIS on a Remote Windows Server\" class=\"read-more\" href=\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/\" aria-label=\"Read more about How to Install and Configure IIS on a Remote Windows Server\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":4,"footnotes":""},"categories":[5],"tags":[],"class_list":["post-736","post","type-post","status-publish","format-standard","hentry","category-tutorials-guides"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to Install and Configure IIS on a Remote Windows Server - Windows VPS Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Install and Configure IIS on a Remote Windows Server\" \/>\n<meta property=\"og:description\" content=\"How to Install and Configure IIS on a Remote Windows Server\" \/>\n<meta property=\"og:url\" content=\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/\" \/>\n<meta property=\"og:site_name\" content=\"Windows VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-11T23:21:28+00:00\" \/>\n<meta name=\"author\" content=\"windows-vps\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"windows-vps\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/\",\"url\":\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/\",\"name\":\"How to Install and Configure IIS on a Remote Windows Server - Windows VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\"},\"datePublished\":\"2026-09-11T23:21:28+00:00\",\"author\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58\"},\"breadcrumb\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/windows-vps.org\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Install and Configure IIS on a Remote Windows Server\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\",\"url\":\"https:\/\/windows-vps.org\/blog\/\",\"name\":\"Windows VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/windows-vps.org\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58\",\"name\":\"windows-vps\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g\",\"caption\":\"windows-vps\"},\"sameAs\":[\"https:\/\/windows-vps.org\/blog\"],\"url\":\"https:\/\/windows-vps.org\/blog\/author\/myxiechengxuan\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Install and Configure IIS on a Remote Windows Server - Windows VPS Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/","og_locale":"en_US","og_type":"article","og_title":"How to Install and Configure IIS on a Remote Windows Server","og_description":"How to Install and Configure IIS on a Remote Windows Server","og_url":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/","og_site_name":"Windows VPS Blog","article_published_time":"2026-09-11T23:21:28+00:00","author":"windows-vps","twitter_card":"summary_large_image","twitter_misc":{"Written by":"windows-vps","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/","url":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/","name":"How to Install and Configure IIS on a Remote Windows Server - Windows VPS Blog","isPartOf":{"@id":"https:\/\/windows-vps.org\/blog\/#website"},"datePublished":"2026-09-11T23:21:28+00:00","author":{"@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58"},"breadcrumb":{"@id":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/windows-vps.org\/blog\/install-configure-iis-remote-windows-server\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/windows-vps.org\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Install and Configure IIS on a Remote Windows Server"}]},{"@type":"WebSite","@id":"https:\/\/windows-vps.org\/blog\/#website","url":"https:\/\/windows-vps.org\/blog\/","name":"Windows VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/windows-vps.org\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58","name":"windows-vps","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g","caption":"windows-vps"},"sameAs":["https:\/\/windows-vps.org\/blog"],"url":"https:\/\/windows-vps.org\/blog\/author\/myxiechengxuan\/"}]}},"_links":{"self":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/comments?post=736"}],"version-history":[{"count":1,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/736\/revisions"}],"predecessor-version":[{"id":739,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/736\/revisions\/739"}],"wp:attachment":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/media?parent=736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/categories?post=736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/tags?post=736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}