Forever Breathes The Lonely Word - My Tech Blog

There are currently no feeds available for new posts, but then again I don't have that many new posts anyways.

Nowadays everybody and their brother try to install their own root certificate into your Windows machine.

Sometimes they have a good reason, like Fiddler, but sometimes they don't.

Sir Mark Russinovich's added a feature to his old utitlity sigcheck.exe

using the -tv switch the program checks all certificates in the user or machine store and finds the ones that are not rooted in Microsoft trusted root certificate list.

So Microsoft keeps a master list of all the CA root certificates it trusts, and any certificate on your machine should be signed directly or via an intermediate by one of this certificates.

So the program shows a nice list of certificates that are not and you should review them and either delete them or make a mental note that they are okay.

Sometime in the future you run sigcheck again and you have to do the same.

Wouldn't it be easier to have it running periodically and alert you if any certs show up in the list. Also it would be nice to have a list of exceptions that are not signed by a trusted CA but still trusted by you, maybe because you created them yourself.

So I need something that would run every day, can give me alerts and allows for some configuration.

Luckily, I already had ServerMonitor.ps1 a PowerShell script that I created in 2007 and that has evolved over the years.

It checks various aspects of your Windows OS and alerts you via various methods. It has a plugin architecture, both providers that collect data and logger that send the result can be added by just dropping a file into the correct directory.

So, all I had to do is writing a new ServerMonitor3 provider that calls sigcheck to do the actual work.

Get the required files

Get sigcheck from TechNet, unblock and unzip it and put the files in a directory of your choice.

Go to my downloads page and get ServerManager3. Unblock the file and unzip it. All files should stay together but you can just drop them anywhere you want.

Configure ServerMonitor

In the same directory create a new text file name ServerMonitor3.xml, this is the default configuration file for ServerMonitor, but you could have many different ones if you want.

Edit the file, start with this:

<?xml version="1.0"?>
<servermonitor version="3.0">

    <console enabled="true" />

  <certificates helper="C:\tools\sigcheck64.exe" store="machine" >


We define a single logger, just on the PowerShell console and a single provider the Certificates checker.

Now we have to tell it where sigcheck.exe is located, edit the helper attribute of the certificates node.

Now we can run the script:

  C:\tools\servermonitor3\ServerMonitor2.ps3 -verbose

You have to adjust the path of course, the -verbose switch is just there so we see a little bit more what's going on, you don't need it.

If everything is fine, you will see a green success message, or you see some information about some certificates in yellow.

Now review these using certmgr.msc.

If you find you want to trust certain certificates, add them to your configuration file:

<certificates helper="C:\tools\sigcheck64.exe" store="machine" >
  <allow thumbprint="7E93B6DB9CB2E2D5A412628AE3C55D66DB1DF02620" remark="myCA" /> 
  <allow thumbprint="C6C256DB9CB2EADFA41262E9FCE6DB9CB243DCB381" remark="Corp Root CA" /> 

The next time you run the script, it wont any longer complain about these.

Just having the results shown on the command line is not very helpful, you want to configure additional logger, the email one is most handy, the file one is also nice for logging purposes.

See the ServerMonitor page on how to configure these loggers.

Set up a scheduled task

Finally you want to run ServerMonitor every so often, set up a Windows Scheduled task to run the script.

Tags: IT Pro

In the past when I was thinking about elevation of a user I always thought about elevating a member of the administrators group from a Medium Integrity Level to a High one.

But elevation is not only for administrators, it also works for any user that gets a split security token at login time.

For example any members of the Power Users or Backup Operators groups, have a split-personality as well.

When normally logging on as such a user and run something as admin, the UAC prompt comes up:

UAC Prompt

The wording here is actually incorrect, I don't have to type an administrator password, Joe Block is not an administrator, but his password gets me past the UAC prompt.

whoami /groups as a normal user:

 Group Name                             Type             SID          Attributes
 ====================================== ================ ============ ==================================================
 Everyone                               Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
 BUILTIN\Users                          Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
 BUILTIN\Power Users                    Alias            S-1-5-32-547 Group used for deny only
 Mandatory Label\Medium Mandatory Level Label            S-1-16-8192

We can see the Power Users group is not in effect: Group used for deny only, any action that requires this membership will fail.

whoami /groups as a elevated user:

 Group Name                                  Type             SID          Attributes
 =========================================== ================ ============ ==================================================
 Everyone                                    Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
 BUILTIN\Users                               Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
 BUILTIN\Power Users                         Alias            S-1-5-32-547 Mandatory group, Enabled by default, Enabled group
 Mandatory Label\Medium Plus Mandatory Level Label            S-1-16-8448

Now, elevated the second part of the split-token is in effect and we are a proper Power User

whoami /groups as elevated member of Backup Operators:

 Group Name                           Type             SID          Attributes
 ==================================== ================ ============ ==================================================
 Everyone                             Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
 BUILTIN\Remote Desktop Users         Alias            S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
 BUILTIN\Backup Operators             Alias            S-1-5-32-551 Mandatory group, Enabled by default, Enabled group
 Mandatory Label\High Mandatory Level Label            S-1-16-12288

The difference between the last two is that a backup operator gets a integery level of High while the power user only gets Medium Plus (what ever that means).

Now my question, sometimes I need to run a elevated process for such a user while a different (standard user) is logged on to Windows.

It is easy to start a non-elevated process. I can use the (Shift+)context menu to Run as different user, use runas.exe or PowerShell:

start-process -verb runas powershell.exe

Only shows me real administrators in the UAC prompt.

I tried other elevation tools, but they all bring up the same UAC prompt.

Even the following doesn't work:

$someCredentials = Get-Credential
Start-Process powershell -Credential $someCredentials -ArgumentList '-noprofile -command &{Start-Process powershell.exe -verb runas}'

I still get a UAC prompt without the non-admin account I want to use.

My UAC level is: Default - Always notify me when: (slider at the top) and I don't want to change that.

The only solution I found so far, only works if I already have an elevated administrator PowerShell running, then I can use:

psexec.exe -u USERNAME -p PASSWORD -d -h -i -accepteula $env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe

I'm using psexec, which has the -h switch meaning: run the process with the account's elevated token, if available. I also have to specify the username and the password for the account.

I think elevating a user should be possible without the help of an administrator but I don't know how. psexc.exe gives me Access Denied if I run it as a non-admin.

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 of 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

04-Aug - Updating Windows 10 with a different OS language.
01-Aug - Protect your local file backup from Ransomware
30-Jul - Windows Groups
23-Jul - Making sure to use only valid certificate authorities
18-Jul - How to elevate a non-admin user in Windows while logged in as a different user?
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