65.9K
CodeProject 正在变化。 阅读更多。
Home

通过 ASP.NET 使用 WMI 函数

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (3投票s)

2009年2月10日

CPOL

3分钟阅读

viewsIcon

39880

从代码中向 IIS 6 添加网站、虚拟文件夹和主机头。

引言

本文演示了如何在 ASP.NET 中使用 WMI 创建网站、添加虚拟文件夹和添加主机头。 我已使用 Windows Server 2003 和 IIS 6 对其进行了测试。

我花了三天时间才能使其正常工作,花了一些时间编写代码,剩下的时间是找出我为什么收到Win32:访问被拒绝错误。 我当然可以弄清楚NETWORK SERVICEIUSR_<服务器名>帐户都没有太多权限。 但是,我不知道 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 以运行此代码,那就太好了。 正如我之前提到的,我是通过尝试才发现这一点的,所以我不知道这是否是解决问题的最佳方案。

如果有人在运行此代码时遇到任何问题,我很乐意提供更多帮助。

© . All rights reserved.