通过 ASP.NET 使用 WMI 函数
从代码中向 IIS 6 添加网站、虚拟文件夹和主机头。
引言
本文演示了如何在 ASP.NET 中使用 WMI 创建网站、添加虚拟文件夹和添加主机头。 我已使用 Windows Server 2003 和 IIS 6 对其进行了测试。
我花了三天时间才能使其正常工作,花了一些时间编写代码,剩下的时间是找出我为什么收到Win32:访问被拒绝错误。 我当然可以弄清楚NETWORK SERVICE或IUSR_<服务器名>帐户都没有太多权限。 但是,我不知道 WMI 和 IIS 元数据库安全性是如何工作的。 其实我还是不太懂。 不过,我解决了我的问题。
使用代码
要从 Internet Information Services Manager 获取网站 ID,请单击“网站”节点,然后在“标识符”列中查看 ID。 默认网站的 ID 始终为 1。
我们将使用的函数位于此命名空间中,因此请包含它
using System.Management;
因此,变量“ServerName
”。 这是您放置服务器名称的地方,如果是您运行代码的服务器,则放置一个点。
要创建网站,您需要使用以下函数。 它返回网站的 ID,您可以在后面提到的函数中使用该 ID。
public static string CreateWebsite(string serverName, string appPoolName, string ip,
string pathToRoot, string hostName, string domainName, int port)
{
ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.Connect;
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
ManagementScope scope = new ManagementScope(string.Format(@\\{0}\root\MicrosoftIISv2,
serverName), options);
scope.Connect();
ManagementObject oW3SVC = new ManagementObject(scope,
new ManagementPath(@"IIsWebService='W3SVC'"), null);
ManagementBaseObject[] serverBindings = new ManagementBaseObject[1];
serverBindings[0] = CreateServerBinding(scope,
string.Format("{0}.{1}", hostName, domainName), ip, port);
ManagementBaseObject inputParameters = oW3SVC.GetMethodParameters("CreateNewSite");
inputParameters["ServerComment"] = string.Format("{0}.{1}", hostName, domainName);
inputParameters["ServerBindings"] = serverBindings;
inputParameters["PathOfRootVirtualDir"] = pathToRoot;
ManagementBaseObject outParameter =
oW3SVC.InvokeMethod("CreateNewSite", inputParameters, null);
string siteId = Convert.ToString(
outParameter.Properties["ReturnValue"].Value).Replace(
"IIsWebServer='W3SVC/", "").Replace("'", "");
ManagementObject oWebVirtDir = new ManagementObject(scope,
new ManagementPath(string.Format(
@"IIsWebVirtualDirSetting.Name='W3SVC/{0}/root'", siteId)), null);
oWebVirtDir.Properties["AppFriendlyName"].Value =
string.Format("{0}.{1}", hostName, domainName);
oWebVirtDir.Properties["AccessRead"].Value = true;
oWebVirtDir.Properties["AuthFlags"].Value = 5; // Integrated Windows Auth.
oWebVirtDir.Properties["AccessScript"].Value = true;
oWebVirtDir.Properties["AuthAnonymous"].Value = true;
oWebVirtDir.Properties["AppPoolId"].Value = appPoolName;
oWebVirtDir.Put();
ManagementObject site = new ManagementObject(scope,
new ManagementPath(Convert.ToString(
outParameter.Properties["ReturnValue"].Value)), null);
site.InvokeMethod("Start", null);
return siteId;
}
要添加虚拟文件夹
public static void AddVirtualFolder(string serverName, string websiteId,
string name, string path)
{
ManagementScope scope = new ManagementScope(
string.Format(@"\\{0}\root\MicrosoftIISV2", serverName));
scope.Connect();
string siteName = string.Format("W3SVC/{0}/Root/{1}", websiteId, name);
ManagementClass mc = new ManagementClass(scope,
new ManagementPath("IIsWebVirtualDirSetting"), null);
ManagementObject oWebVirtDir = mc.CreateInstance();
oWebVirtDir.Properties["Name"].Value = siteName;
oWebVirtDir.Properties["Path"].Value = path;
oWebVirtDir.Properties["AuthFlags"].Value = 5; // Integrated Windows Auth.
oWebVirtDir.Properties["EnableDefaultDoc"].Value = true;
// date, time, size, extension, longdate ;
oWebVirtDir.Properties["DirBrowseFlags"].Value = 0x4000003E;
oWebVirtDir.Properties["AccessFlags"].Value = 513; // read script
oWebVirtDir.Put();
ManagementObject mo = new ManagementObject(scope,
new System.Management.ManagementPath("IIsWebVirtualDir='" +
siteName + "'"), null);
ManagementBaseObject inputParameters = mo.GetMethodParameters("AppCreate2");
inputParameters["AppMode"] = 2;
mo.InvokeMethod("AppCreate2", inputParameters, null);
mo = new ManagementObject(scope, new System.Management.ManagementPath(
"IIsWebVirtualDirSetting='" + siteName + "'"), null);
mo.Properties["AppFriendlyName"].Value = name;
mo.Put();
}
要将主机头添加到网站
public static void AddHostHeader(string serverName, string hostHeader,
string ip, int port, string websiteID)
{
ManagementScope scope = new ManagementScope(string.Format(
@"\\{0}\root\MicrosoftIISV2", serverName));
scope.Connect();
string siteName = string.Format("'W3SVC/{0}'", websiteID);
ManagementObject mo = new ManagementObject(scope,
new System.Management.ManagementPath("IIsWebServerSetting=" + siteName), null);
ManagementBaseObject[] websiteBindings =
(ManagementBaseObject[])mo.Properties["ServerBindings"].Value;
ManagementObject mco = CreateServerBinding(scope, hostHeader, ip, port);
ManagementBaseObject[] newWebsiteBindings =
new ManagementBaseObject[websiteBindings.Length+1];
websiteBindings.CopyTo(newWebsiteBindings, 0);
newWebsiteBindings[newWebsiteBindings.Length - 1] = mco;
mo.Properties["ServerBindings"].Value = newWebsiteBindings;
mo.Put();
}
最后但并非最不重要的一点是,添加以下函数。 它创建一个用于服务器绑定的对象
private static ManagementObject CreateServerBinding(ManagementScope scope,
string hostName, string ip, int port)
{
ManagementClass mc = new ManagementClass(scope,
new ManagementPath("ServerBinding"), null);
ManagementObject mco = mc.CreateInstance();
mco.Properties["Hostname"].Value = hostName;
mco.Properties["IP"].Value = ip;
mco.Properties["Port"].Value = port;
mco.Put();
return mco;
}
关注点
安全性。 这不会像这样运行。 在我尝试过的数百万件事中,似乎需要做两件事。 WMI 和 IIS 元数据库访问。
默认情况下,Windows Server 2003 和 IIS 6.0 在NETWORK SERVICE下运行 ASP.NET。 但是,我们将使用模拟。
所以您想将此添加到您的web.config
<identity impersonate="true" />
用于授予您访问 IIS metaBase 的权限的帐户将是IUSR_<服务器名>帐户。 我将继续将此帐户称为IUSR_。 你知道你必须附加你的服务器名称。
WMI 权限
- 转到控制面板 -> 管理工具 -> 计算机管理 -> 服务和应用程序。
- 右键单击 WMI 控件,选择属性。
- 单击安全性。
- 打开树。
- 单击 MicrosoftIISv2。
- 单击安全性。
- 单击高级。
- 双击IUSR_(如果它不存在,则添加它)。
- 选择“应用到”:此命名空间和子命名空间。
- 选中所有复选框。
- 应用并关闭所有对话框。
IIS 元数据库权限
- 下载并安装 IIS 6 Resource Kit。
- 运行 MetaBase Explorer(在“开始”下的 Resource Kit 菜单中找到它)。
- 打开树,然后右键单击第一个或第二个节点,然后选择“权限”。
- 如果它抱怨当前密钥从 / 继承,请单击“是”。
- 单击IUSR_或添加它。
- 选中“完全控制”。
- 应用并关闭所有对话框。
您应该准备好以足够的权限运行。
如果更有经验的人可以对此发表评论并指出如何正确配置 IIS 和 WMI 以运行此代码,那就太好了。 正如我之前提到的,我是通过尝试才发现这一点的,所以我不知道这是否是解决问题的最佳方案。
如果有人在运行此代码时遇到任何问题,我很乐意提供更多帮助。