Introduction
There are situations where we would need to restart IIS application pools remotely via C#. This tip aims to achieve that with any IIS installed destination server.
Background
There are many ways to check status, stop, start the application pools on remote servers. Even though System.DirectoryService.DirectoryEntry
method provides simple 3 lines of code to do that, still we are in need of a cleaner code which can perform the action under restricted environments as well.
WMI provides us vast methods to accomplish the task. This code uses both C# and WMI methods to provide a robust application which will work in 99.99% of environments (0.1% exception may exist on very highly secured environments).
IIS and Application Pool Concept
Internet Information Services, IIS is an extensible web server created by Microsoft for use with Windows family. IIS supports HTTP, HTTPS, FTP, FTPS, SMTP and NNTP.
We can separate different Web applications and Web sites into groups known as application pools. An application pool is a group of one or more URLs that are served by a worker process or set of worker processes. Any Web directory or virtual directory can be assigned to an application pool.
Use multiple application pools when you want to help ensure that applications and Web sites are confidential and secure. For example, an enterprise organization might place its human resources Web site and its finance Web site on the same server, but in different application pools.
IIS WMI Provider
Like other options like services, computer details, processes, etc., IIS can also be controlled by WMI. Classes are implemented by the IIS WMI provider in the MicrosoftIISv2
namespace. Starting Windows XP and Windows server 2003 SP1, any script that uses WMI to access IIS remotely, must encrypt the connection, else it will fail with WBEM_ACCESS_DENIED
error. This authentication property must be set during the call.
Code # 1
The below code contains two functions: one to determine the status of an application pool:
private bool IsApplicationPoolRunning(string servername, string strAppPool)
{
string sb = "";
ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.PacketPrivacy;
options.EnablePrivileges = true;
ManagementScope scope = new ManagementScope(@"\\" +
servername + "\\root\\MicrosoftIISv2", options);
ObjectQuery oQueryIISApplicationPoolSetting =
new ObjectQuery("SELECT * FROM IISApplicationPoolSetting");
ManagementObjectSearcher moSearcherIISApplicationPoolSetting =
new ManagementObjectSearcher(scope, oQueryIISApplicationPoolSetting);
ManagementObjectCollection collectionIISApplicationPoolSetting =
moSearcherIISApplicationPoolSetting.Get();
foreach (ManagementObject resIISApplicationPoolSetting
in collectionIISApplicationPoolSetting)
{
if (resIISApplicationPoolSetting
["Name"].ToString().Split('/')[2] == strAppPool)
{
if (resIISApplicationPoolSetting["AppPoolState"].ToString() != "2")
{
return false;
}
}
}
return true;
}
Code Explanation
- Add
System.Management
reference to the code
- First, we need to configure connection options for WMI
- Authentication level is set to
PacketPrivacy
to enable authentication with encryption
- As needed, set
EnablePriviliges
to true
(IIS operations don't need this, but in case web server is highly secured, sometimes we might need this)
- Connect to
MicrosoftIISv2
namespace with the WMI options
- Query IIS WMI property
IISApplicationPoolSetting
which will contain application pool name and its status
- As needed, interpret the properties
Name
and AppPoolState
to get the result.
Code # 2
public void performRequestedAction(String servername, String AppPoolName, String action)
{
StringBuilder sb = new StringBuilder();
ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.PacketPrivacy;
options.EnablePrivileges = true;
ManagementScope scope = new ManagementScope(@"\\" +
servername + "\\root\\MicrosoftIISv2", options);
ObjectQuery oQueryIISApplicationPool =
new ObjectQuery("SELECT * FROM IISApplicationPool");
ManagementObjectSearcher moSearcherIISApplicationPool =
new ManagementObjectSearcher(scope, oQueryIISApplicationPool);
ManagementObjectCollection collectionIISApplicationPool =
moSearcherIISApplicationPool.Get();
foreach (ManagementObject resIISApplicationPool in collectionIISApplicationPool)
{
if (resIISApplicationPool["Name"].ToString().Split('/')[2] == AppPoolName)
{
resIISApplicationPool.InvokeMethod(action, null);
}
}
}
Code Explanation
- Here, we use
IISApplicationPool
just to retrieve the name of the application pool and invoke methods like start
, stop
, recycle the application pool as needed.
- Other code explanations are the same as above:
if (!IsApplicationPoolRunning("localhost","DefaultAppPool"))
{
performRequestedAction("localhost", "DefaultAppPool", "stop");
performRequestedAction("localhost", "DefaultAppPool", "start");
}
Replace localhost
with any remote machine and DefaultAppPool
with any application pool as needed.
References
- Packet Privacy and other DCOM config details - https://support.microsoft.com/en-us/kb/176799
- IIS WMI - https://msdn.microsoft.com/en-us/library/ms525265(v=vs.90).aspx
History
- 1st revision - 12-Dec-2015