IISRESET internals

 

I recently worked on an incident dealing with IIS6/Windows 2003 and IISRESET failing on the 1st attempt with the following error: "Restart attempt failed. Access Denied".
The strange thing is that running IISRESET a second time was working with no issue.

I'm not going to start a long discussion on the supportability of using IISRESET but you may be aware of this statement:

[Event ID 3206 — IIS Reset Activity ]

Note: Restarting or stopping IIS, or rebooting your Web server, is a severe action. When you restart the Internet service, changes to the metabase can be lost. All sessions connected to your Web server are dropped, and any data held in Web applications is lost. All Internet sites are unavailable until Internet services are restarted. For these reasons, the use of IISReset is not recommended

[…]

The use of IISReset is not recommended on IIS 6.0 and is not supported on IIS 7.0 or IIS 7.5

When you run IISRESET with no arguments on a Windows 2003 server, IISRESET just calls a method exposed in a COM object hosted in a process named IISRSTAS.EXE.
The main actions to "RESET IIS" are done in this IISRSTAS process and the code executed consists in the following actions:

  1. stopping the IISADMIN service
  2. if the IISADMIN service fails to stop, enumerating all processes trying to find and kill processes hosting IISW3ADM.DLL

In most case, only step 1) is executed and, on IIS6, IISRESET is very similar to "NET STOP IISADMIN /Y". However, if the IISADMIN service can't be stopped in a timely fashion, the action taken is quite rude: killing all processes hosting IISW3ADM.DLL! In my customer's scenario, the request to stop the IISADMIN service was failing with an error 0x80070425 (The service cannot accept control messages at this time) and therefore, IISRSTAS.EXE starts to enumerate all processes trying to find processes hosting IISW3ADM. In order to find the processes hosting IISW3ADM.DLL, IISRSTAS.EXE had to call OpenProcess() to enumerate DLLs loaded in each process and the OpenProcess() call was failing on one specific process (RPCSS).

In the end, the solution was simply to use IISRESET /NOFORCE. In this case, IISRESET only executes step 1) and does not throw an error.

If you still want to restart IIS, you may use IISRESET /NOFORCE. On IIS6/Windows 2003, an alternative consists in stopping the IISADMIN service and restarting W3SVC:

NET STOP IISADMIN /Y && NET START W3SVC

If you use IIS7+ versions, you may use this command (on IIS7+, IISADMIN is just there for IIS6 compatibility):

NET STOP WAS /Y && NET START W3SVC

If you want to stop IIS and the HTTP transport (HTTP.SYS), you can use this command:

NET STOP HTTP /Y && NET START W3SVC

Note that the above command is quite handy in case you are changing SSL configuration and you want your change to be effective without rebooting the server (for example, if you add a root CA to the computer account certificate store or change some SSL setting like SendTrustedIssuerList)

I hope this blog clarifies the reason why you shouldn't use IISRESET without the /NOFORCE option!

Emmanuel Boersma