通过 C# 操作 IIS 应用程序池






3.33/5 (3投票s)
一篇文章,描述了如何通过 C# 控制 IIS 应用程序池的操作。
引言
在某些情况下,我们需要通过 C# 远程重启 IIS 应用程序池。本技巧旨在实现这一点,适用于任何已安装 IIS 的目标服务器。
背景
有很多方法可以检查状态、停止和启动远程服务器上的应用程序池。虽然 System.DirectoryService.DirectoryEntry
方法提供了执行此操作的简单三行代码,但我们仍然需要一个更简洁的代码,以便在受限的环境下执行操作。
WMI 为我们提供了大量方法来完成这项任务。此代码同时使用 C# 和 WMI 方法,提供一个健壮的应用程序,可以在 99.99% 的环境中工作(在非常安全的的环境中,可能存在 0.1% 的例外情况)。
IIS 和应用程序池概念
Internet Information Services (IIS) 是微软为 Windows 系列创建的可扩展的 Web 服务器。IIS 支持 HTTP、HTTPS、FTP、FTPS、SMTP 和 NNTP。
我们可以将不同的 Web 应用程序和网站分成称为应用程序池的组。应用程序池是由一个或多个 URL 组成的组,由工作进程或一组工作进程提供服务。任何 Web 目录或虚拟目录都可以分配到应用程序池。
当您希望确保应用程序和网站的机密性和安全性时,请使用多个应用程序池。例如,一家企业组织可以将人力资源网站和财务网站放在同一服务器上,但位于不同的应用程序池中。
IIS WMI 提供程序
与其他选项(如服务、计算机详细信息、进程等)一样,IIS 也可以通过 WMI 进行控制。类由 IIS WMI 提供程序在 MicrosoftIISv2
命名空间中实现。从 Windows XP 和 Windows Server 2003 SP1 开始,任何使用 WMI 远程访问 IIS 的脚本都必须加密连接,否则将出现 WBEM_ACCESS_DENIED
错误。必须在调用期间设置此身份验证属性。
代码 # 1
下面的代码包含两个函数:一个用于确定应用程序池的状态
private bool IsApplicationPoolRunning(string servername, string strAppPool)
{
string sb = ""; // String to store return value
// Connection options for WMI object
ConnectionOptions options = new ConnectionOptions();
// Packet Privacy means authentication with encrypted connection.
options.Authentication = AuthenticationLevel.PacketPrivacy;
// EnablePrivileges : Value indicating whether user privileges
// need to be enabled for the connection operation.
// This property should only be used when the operation performed
// requires a certain user privilege to be enabled.
options.EnablePrivileges = true;
// Connect to IIS WMI namespace \\root\\MicrosoftIISv2
ManagementScope scope = new ManagementScope(@"\\" +
servername + "\\root\\MicrosoftIISv2", options);
// Query IIS WMI property IISApplicationPoolSetting
ObjectQuery oQueryIISApplicationPoolSetting =
new ObjectQuery("SELECT * FROM IISApplicationPoolSetting");
// Search and collect details thru WMI methods
ManagementObjectSearcher moSearcherIISApplicationPoolSetting =
new ManagementObjectSearcher(scope, oQueryIISApplicationPoolSetting);
ManagementObjectCollection collectionIISApplicationPoolSetting =
moSearcherIISApplicationPoolSetting.Get();
// Loop thru every object
foreach (ManagementObject resIISApplicationPoolSetting
in collectionIISApplicationPoolSetting)
{
// IISApplicationPoolSetting has a property called Name which will
// return Application Pool full name /W3SVC/AppPools/DefaultAppPool
// Extract Application Pool Name alone using Split()
if (resIISApplicationPoolSetting
["Name"].ToString().Split('/')[2] == strAppPool)
{
// IISApplicationPoolSetting has a property
// called AppPoolState which has following values
// 2 = started 4 = stopped 1 = starting 3 = stopping
if (resIISApplicationPoolSetting["AppPoolState"].ToString() != "2")
{
return false;
}
}
}
return true;
}
代码解释
- 将
System.Management
引用添加到代码中 - 首先,我们需要配置 WMI 的连接选项
- 将身份验证级别设置为
PacketPrivacy
以启用加密身份验证 - 根据需要,将
EnablePriviliges
设置为true
(IIS 操作不需要此设置,但在 Web 服务器高度安全的情况下,有时我们可能需要此设置) - 使用 WMI 选项连接到
MicrosoftIISv2
命名空间 - 查询 IIS WMI 属性
IISApplicationPoolSetting
,它将包含应用程序池名称及其状态 - 根据需要,解释属性
Name
和AppPoolState
以获取结果。
代码 # 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);
// IIS WMI object IISApplicationPool to perform actions on IIS Application Pool
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)
{
// InvokeMethod - start, stop, recycle can be passed as parameters as needed.
resIISApplicationPool.InvokeMethod(action, null);
}
}
}
代码解释
- 在这里,我们使用
IISApplicationPool
只是为了检索应用程序池的名称并调用方法,如start
、stop
、根据需要回收应用程序池。 - 其他代码说明与上述相同
// Is any result other that started
if (!IsApplicationPoolRunning("localhost","DefaultAppPool"))
{
// stop and start the pool
performRequestedAction("localhost", "DefaultAppPool", "stop");
performRequestedAction("localhost", "DefaultAppPool", "start");
}
将 localhost
替换为任何远程机器,并将 DefaultAppPool
替换为任何应用程序池,根据需要进行更改。
参考文献
- 数据包隐私和其他 DCOM 配置详细信息 - https://support.microsoft.com/en-us/kb/176799
- IIS WMI - https://msdn.microsoft.com/en-us/library/ms525265(v=vs.90).aspx
历史
- 首次修订 - 2015 年 12 月 12 日