Forever Breathes The Lonely Word - My Tech Blog

March 20th 2015 - I moved Blog Software again, actually rather than using some dedicated Blog software, I'm now using my own CMS for the blog. This means a single system for all content.
There are currently no feeds available for new posts, but then again I don't have that many new posts anyways.

July 11th 2015 - I have enabled comments on certain posts, just to experience with Disqus a bit, looks good so far.

IIS - Nested comments in config files

Published: 27 August 2015

One nice feature of XML based configuration is that you can add comments anywhere to explain why a certain configuration value has been set this way.

For IIS I use this most often to comment on the IP addresses I use to allow for certain sites, like:

        <ipSecurity allowUnlisted="false">
            <!-- Susan's laptop -->
            <add ipAddress="" allowed="true"/>
            <!-- public IP at work -->
            <add ipAddress="" allowed="true" />
            <!-- local home network -->
            <add ipAddress="" subnetMask="" allowed="true" />
            <!-- explicit deny Mark's network -->
            <add ipAddress="" subnetMask="" allowed="false" /> 

without these comments I would sometime come back to the configuration and would not know what these addresses are and whether I would still need them.

The other day I had to allow access to a site from everywhere, I could not just change the 'allowUnlisted' value because I have both 'allow' and 'deny' entries in the list.

Normally I would just comment out the whole 'ipSecurity' node, but this isn't possible because XML does not allow nested comments.

My first fix was to move the specific comments out of the node into its own comment section, that works but it's a pain if you have many comments and you are loosing the direct association with the add node.

<!-- ipSecurity info: = Susan's laptop = public IP at work

A cleaner solution is to extend the IIS schema to allow a comment directly on the 'add' node.

To do that I created a new file:
with the following content:
    <sectionSchema name="system.webServer/security/ipSecurity"> 
        <collection addElement="add" >
           <attribute name="remark" type="string" defaultValue=""  />
I'm adding a new attribute to the 'add' node, which allows me to add my comment directly on the node like this:
        <ipSecurity allowUnlisted="false">
            <add ipAddress="" allowed="true" remark="Susan's laptop" />
            <add ipAddress="" allowed="true" remark="public IP at work" />
            <add ipAddress="" subnetMask="" allowed="true" remark="local home network" />
            <add ipAddress="" subnetMask="" allowed="false" remark="explicit deny Mark's network" /> 

This doesn't show up in the IIS Manager UI, but in the configuration editor:

config editor

This means I can edit my comments in the GUI and don't have to edit the config file directly anymore.

If you use that web.config on a different server you have to remember to copy the 'my_schema.xml' file as well, otherwise you will get a '500.19' configuration error complaining:

Unrecognized attribute 'remark'

New features in IIS 10

Published: 15 July 2015

In all the news about Windows 10 and Windows Server 2016, I haven't read anything about new features in IIS except for the support of HTTP/2.

Maybe there is something else?

I'm looking at Server 2016 Technical Preview 2 (Build 10074), and Windows 10 (Build 10240) which seems to be no different in respect of IIS.

Support for HTTP/2

In Server 2016 TP2 and current builds of Windows 10, HTTP/2 is enabled by default, no need to set the DuoEnabled value in the registry, no need for a reboot.

To verify that your are now using HTTP/2, open Chrome and connect to your secure site hosted on IIS 10. In a second tab, type the following:


You may have to refresh your page, but you should see your request listed with a Protocol Negotiated value of h2

In Firefox 39, using the F12 tools, the Headers on the Network tab show: Version: HTTP/2.0


IE 11 or Edge don't seem to show any difference in their F12 tools.

Support for Wildcard host header

A feature many people asked about for a long time is the support of wildcard host headers. In older versions of IIS up to 8.5 you could only specify a full host name in the bindings for a web site.

In IIS 10 you can now do:

New-WebBinding -Name "Default Web Site" -IPAddress "*" -Port 80 -HostHeader "*"

and your bindings are:

ls iis:\sites
Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Default Web Site 1    Started    %SystemDrive%\inetpub\wwwroot  http *:80:
                                                                https *:443: sslFlags=0
                                                                http *:80:*

This means you can easily point multiple host names to the same site.

I never needed this, but for some people it's a big deal. There is a long thread on about this.

You can now use and and as long as you have your DNS server or hosts file set up, they both go to the same site.

What about - Doesn't work, the wildcard * stands for a single "word", using a binding of *.* is invalid, same for foo.*.bar. The wildcard has to be the leftmost character. An No: *.bar doesn't work.

To make this work you have to add a binding:

New-WebBinding -Name "Default Web Site" -IPAddress "*" -Port 80 -HostHeader "*"

But I think that is fair enough.

More information on

New IISAdministration PowerShell module

While the existing PowerShell module (WebAdministration) has hardly changed, the IIS team added a second module with direct access to the underlaying 'Microsoft.Web.Administration.ServerManager' object.

The big thing here is much better support for the PowerShell pipeline.

Get-command -Module IISAdministration | Select Name

You can read more about it in Baris Caglar's Blog, a list of all new cmdlets is on TechNet

Environment Variables for Applications Pools

We can set specific environment variables per app pool. There is not UI for this yet.

Add-WebConfigurationProperty -value @{name='TestVar';value='42'} -filter "system.applicationHost/applicationPools/add[@name='DefaultAppPool']/environmentVariables" -pspath 'MACHINE/WEBROOT/APPHOST' -name "." 

Looking at the Worker Process in Process Explorer:

AppPool EnvVar

Support for HTTP status code 308

Used in the HTTP Redirect module, make sure you have that:

Install-WindowsFeature Web-Http-Redirect

then set a new redirect using PermRedirect:

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/Default Web Site'  -filter "system.webServer/httpRedirect" -name "enabled" -value "True"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/Default Web Site'  -filter "system.webServer/httpRedirect" -name "destination" -value ""
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/Default Web Site'  -filter "system.webServer/httpRedirect" -name "httpResponseStatus" -value "PermRedirect"

you now get:


Removal of server header

No UI for this yet, use:

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/Default Web Site'  -filter "system.webServer/security/requestFiltering" -name "removeServerHeader" -value "True"

or one the server level:

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/security/requestFiltering" -name "removeServerHeader" -value "True"

now the header

Server: "Microsoft-IIS/10.0" 
is no longer sent.

Failed Request Tracing

A new failure definition: traceAllAfterTimeout, I'm not sure what this does exactly.

New cipher suites

Windows 10 supports at least two additional cipher suites:


The first one is an important one, because it is very high on the list of cipher suites that Google's Chrome browser is using.

Cipher suites for TLS 1.2 in Windows 10 (as as July 15th 2015):

          ECDHE-RSA-AES256-GCM-SHA384   ECDH-256 bits  256 bits      HTTP 200 OK
          ECDHE-RSA-AES256-SHA384       ECDH-256 bits  256 bits      HTTP 200 OK
          ECDHE-RSA-AES256-SHA          ECDH-256 bits  256 bits      HTTP 200 OK
          ECDHE-RSA-AES256-GCM-SHA384   ECDH-256 bits  256 bits      HTTP 200 OK
          AES256-SHA256                 -              256 bits      HTTP 200 OK
          AES256-SHA                    -              256 bits      HTTP 200 OK
          AES256-GCM-SHA384             -              256 bits      HTTP 200 OK
          ECDHE-RSA-AES128-SHA256       ECDH-256 bits  128 bits      HTTP 200 OK
          ECDHE-RSA-AES128-SHA          ECDH-256 bits  128 bits      HTTP 200 OK
          ECDHE-RSA-AES128-GCM-SHA256   ECDH-256 bits  128 bits      HTTP 200 OK
          RC4-SHA                       -              128 bits      HTTP 200 OK
          RC4-MD5                       -              128 bits      HTTP 200 OK
          AES128-SHA256                 -              128 bits      HTTP 200 OK
          AES128-SHA                    -              128 bits      HTTP 200 OK
          AES128-GCM-SHA256             -              128 bits      HTTP 200 OK
          DES-CBC3-SHA                  -              112 bits      HTTP 200 OK

To get such a list download sslyze, unblock and extract the zip, then run:

 .\sslyze.exe --regular

as a standard user

Stopping and removing IIS

Published: 11 July 2015
Stopping IIS
If you temporarily don't use IIS, you can 'turn it off'.
Optionally, stop all web sites, ftp sites and application pools:
ls iis:\sites | stop-website -ErrorAction SilentlyContinue
ls iis:\sites | % {$_.ftpserver.stop()}
ls IIS:\AppPools | Stop-WebAppPool
Stop all related services. Please note that WMSVC and ftpsvc may not be installed on your machine.
Stop-Service WMSVC 
Stop-Service AppHostSvc
Stop-Service W3SVC
Stop-Service ftpsvc
Stop-Service WAS
Disable the services
Set-Service -Name AppHostSvc -StartupType disabled
Set-Service -Name w3svc -StartupType disabled
Set-Service -Name ftpsvc -StartupType disabled
Set-Service -Name WAS -StartupType disabled
Set-Service -Name WMSVC -StartupType disabled
You should see that nobody is listening to any web ports anymore:
netstat -an
To Enable IIS again:
Set-Service -Name AppHostSvc -StartupType Automatic
Set-Service -Name w3svc -StartupType Automatic
Set-Service -Name ftpsvc -StartupType Automatic
Set-Service -Name WAS -StartupType Automatic
Set-Service -Name WMSVC -StartupType Automatic

Start-Service WAS
Start-Service W3SVC
Start-Service ftpsvc
Start-Service AppHostSvc
Start-Service WMSVC

ls iis:\sites | start-website -ErrorAction SilentlyContinue
ls iis:\sites | % {$_.ftpserver.start()}
Removing IIS
Close IIS Manager if you have it running.
Uninstall any IIS Extensions, it's better to do that before uninstalling IIS.
$app = get-WmiObject -Class Win32_Product -namespace "root\cimv2" | Where-object{$_.Name -match "IIS URL Rewrite Module 2"}
We can remove most IIS components with the following command:
Uninstall-WindowsFeature -Name Web-Server -restart
Uninstall-WindowsFeature -Name Was
or on older Windows versions:
dism.exe -online -Disable-Feature -FeatureName:IIS-WebServer
dism.exe -online -Disable-Feature -FeatureName:WAS-WindowsActivationService
There are still some files in "C:\Windows\System32\inetsrv","C:\inetpub" and your content directories. Leave "inetsrv" alone, but you can delete the others.

I often answer questions about IIS on, or and often people provide very little information about their problem. Nearly always it would be helpful to know the sub-status code and people should try a few common troubleshooting things before asking a questions on these forums.

So I decided to write a PowerShell script to be run on the server to perform some tests and even offer to fix certain common problems.

This is work in progress but I have a first working version on GitHub

27-Aug - IIS - Nested comments in config files
15-Jul - New features in IIS 10
11-Jul - Stopping and removing IIS
11-Jul - Test-WebSite PowerShell script to test an IIS site
02-Jul - Different ways for installing Windows features on the command line
26-Jun - IIS - Managing FTP sites with PowerShell
24-May - Enable Telegram portable without a phone.
22-May - Disable the floppy drive on Windows VMs
19-May - Windows Server Operational Modes
17-May - Fixing PowerShell profile to work in Nano Server
25-Mar - IIS Hardening - Miscellaneous
23-Mar - IIS - Troubleshooting using logs
23-Mar - IIS Hardening - File Permissions
22-Mar - IIS Hardening - File Extensions
22-Mar - IIS Hardening - Handler Mappings, Modules and ISAPI Filters
20-Feb - Clone a KeePass database with new credentials in PowerShell
14-Jan - Some stats based on the Sysinternals sysmon service.

older posts

Pages in this section


ASP.Net | Community | Development | IIS | IT Pro | Security | SQL (Server) | Tools | Web | Work on the road