选择预配选项

作者:Tali Smith

介绍

IT 管理员和软件开发人员都需要考虑在托管环境中预配网站。 在 Internet Information Services (IIS) 预配网站可以通过多种方法来执行:

  • 通过 IIS 管理器用户界面 (UI)
  • 以编程方式使用 C#
  • 通过 Windows PowerShell™ 脚本

本文介绍 IT 管理员和软件开发人员的不同选项的优点和缺点,并提供一些示例。 有关详细信息,请参阅 IIS 中的预配选项

使用 UI 或远程委派

可以使用 IIS 管理器(IIS 附带的管理用户界面)配置 ApplicationHost.config 中最常见的属性。打开服务、站点或虚拟目录的属性表并更改值。 更改会立即生效,无需停止和启动服务器。

  • 优点
    创建站点或虚拟目录或配置具有多个属性的功能时,管理用户界面将设置所有支持属性。 IIS 管理器会通知你新值是否无效。
  • 缺点
    通过 Internet 管理大型 IIS 服务器配置或多台服务器可能很慢且繁琐。 并非所有配置属性都可以在用户界面中访问。

有关使用 UI 预配网站的说明,请参阅创建网站 (IIS 7)

使用文本编辑器

可在 IIS 运行时使用文本编辑器(如记事本)直接编辑 ApplicationHost.config 文件。 条目区分大小写。

  • 优点
    可以在一个实例中更改多个属性或创建新节点,而无需打开和关闭多个属性表。
  • 缺点
    使用运行时编辑很容易损坏 IIS 服务器。 如果编辑包含格式不正确的 XML,IIS 将无法读取 ApplicationHost.config,并且必须还原最后一个历史记录文件。 如果编辑包含不符合架构中规则的无效配置,则会在事件查看器中记录错误,但 IIS 的其余部分可以运行。
    在剪切和粘贴 ApplicationHost.config 的部分内容时,必须考虑属性继承。粘贴的部分可能会从父节点继承属性,并将属性传递给子节点。
    如果通过网络使用运行时编辑并且连接失败,则最终可能会生成无效的 ApplicationHost.config。请注意,如果对 Web 场中的多个服务器使用编辑时运行,则所需时间与使用用户界面的时间一样长。

使用 Windows Management Instrumentation (WMI)

可以使用 Windows® Management Instrumentation (WMI) 以编程方式在脚本或已编译的程序中配置 IIS。 更改会立即生效,无需停止和启动服务器。

  • 优点
    使用 WMI 配置大型站点或多台服务器快速高效。WMI 也支持编写脚本。 下面是 WMI 脚本的示例。
  • 缺点
    如果创建了站点或虚拟目录,或使用依赖其他属性的属性,则必须确保知道还需要创建和设置哪些支持属性。

以下代码可用于创建网站和应用程序池。

If WScript.Arguments.Count < 4 Then 
    WScript.Echo "Not enough parameters. Enter: username | web site name | app pool password | site ID" 
    WScript.Quit
End If

userName = WScript.Arguments(0) 
siteName = WScript.Arguments(1)
appPoolPassword = WScript.Arguments(2)
siteID = WScript.Arguments(3) 
appPoolName = "apppool_" & siteName
physicalPath = "\\server\share" & userName & "\" & siteName [slg1] [slg2] 

Set oIIS = GetObject("winmgmts:root\WebAdministration")

Set oBinding = oIIS.Get("BindingElement").SpawnInstance_
oBinding.BindingInformation = "*:80:" & siteName
oBinding.Protocol = "http"

Set oBinding2 = oIIS.Get("BindingElement").SpawnInstance_
oBinding2.BindingInformation = "*:80:www." & siteName
oBinding2.Protocol = "http"
arrBindings = array(oBinding, oBinding2)

Set oSiteDefn = oIIS.Get("Site")
oSiteDefn.Create siteName, arrBindings, physicalPath
WScript.Echo "Site created"

WScript.Sleep(100)

Set oSite = oIIS.Get("Site.Name='" & siteName & "'")
oSite.ID = siteID 
oSite.Put_

Set oSite = oIIS.Get("Site.Name='" & siteName & "'")
appPoolUserName = "poolname_" & siteID

Set oAppDefn = oIIS.Get("ApplicationPool")
oAppDefn.Create appPoolName
WScript.Echo "App pool created"

WScript.Sleep(3000)

Set oAppDefn = oIIS.Get("ApplicationPool.Name='" & appPoolName & "'")
oAppDefn.ProcessModel.IdentityType = 3
oAppDefn.ProcessModel.Username = appPoolUserName
oAppDefn.ProcessModel.Password = appPoolPassword
oAppDefn.Put_ 

WScript.Echo "Identity set for App Pool"

Set oSiteDefn = oIIS.Get("Site.Name='" & siteName & "'")
oSiteDefn.ApplicationDefaults.ApplicationPool = appPoolName
oSiteDefn.Put_
WScript.Echo "Site assigned to pool"

Set oSite = oIIS.Get("Site.Name='" & siteName & "'")
oSite.Start

使用 AppCmd.exe

可以使用 AppCmd.exe 来预配网站以及运行许多命令来编辑配置。

下面的代码示例是可用于创建站点和应用程序池(具有失败请求跟踪和 W3svc 日志文件位置)的代码示例。

%windir%\system32\inetsrv\Appcmd add AppPool -name:%poolname% -processModel.username:%poolaccount% -processModel.password:%poolaccountpwd% -enable32BitAppOnWin64:true

%windir%\system32\inetsrv\AppCmd add site -name:%sitename% -bindings:http/*:80:%sitename% -physicalPath:%sitepath% -logfile.directory:%W3svclogpath% -traceFailedRequestsLogging.directory:%FREBlogpath%

%windir%\system32\inetsrv\Appcmd set app -app.name:%sitename%/ -applicationPool:%poolname%

您可以使用以下代码来配置失败请求跟踪日志文件位置:

%windir%\system32\inetsrv\AppCmd set config <sitename> -section:traceFailedRequestsLogging.directory:\\remoteserver\content$\<sitename>\logs\failedReqLog

可以使用以下代码配置 W3SVC 日志文件位置:

%windir%\system32\inetsrv\AppCmd set config <sitename> -section:-logfile.directory:\\remotefileshare\content$\<sitename>\logs\logfiles

使用托管 API (Microsoft.Web.Administration)

可以使用 Microsoft.Web.Administration 中的托管应用程序编程接口 (API) 在任何 Microsoft® .NET 应用程序中以编程方式配置 IIS。 Microsoft.Web.Administration 是 IIS 中的一个新增 API,允许开发人员使用托管代码轻松取和操作服务器配置。

  • 优点
    使用 Microsoft.Web.Administration 可以快速高效地配置大型站点或多台服务器。 可以使用远程过程调用 (RPC) 管理 Microsoft.Web.Administration 进行远程服务器配置。 Microsoft.Web.Administration 可以在 62 秒内创建多达 100,000 个站点(大约每秒 1,600 个站点)。
  • 缺点
    Microsoft.Web.Administration 只能在 Windows® 操作系统上使用。 Windows Management Instrumentation (WMI)许多对象没有公开为强类型对象,因此,您必须了解更低级别的 API 才能配置某些对象和属性。

下面的代码可用于创建站点和应用程序池以及设置临时编译目录。

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Web.Administration;

namespace IIS7Demos
{
   class CreateSites
   {
      const int NUMBEROFSITES = 100;
      const int SITEBASENUMBER = 1000;
      const string POOLPREFIX = "POOL_";
      const string SITENAMEPREFIX = "SITE";
      const string ROOTDIR = "e:\\content"; 

   static void Main(string[] args)
   { 
      ServerManager mgr = new ServerManager();
      SiteCollection sites = mgr.Sites;

      Stopwatch watch = new Stopwatch();
      watch.Start();

      for (int i = SITEBASENUMBER; i < NUMBEROFSITES+SITEBASENUMBER; i++)
      {
         if (!CreateSitesInIIS(sites, SITENAMEPREFIX, i, ROOTDIR))
         {
            Console.WriteLine("Creating site {0} failed", i);
         }

         if (!CreateAppPoolInIIS(mgr, SITENAMEPREFIX, i))
         {
            Console.WriteLine("Creating apppool {0} failed", i);
         }
      }

      mgr.CommitChanges();
      watch.Stop();
      Console.WriteLine("Creating {0} sites took {1} seconds", NUMBEROFSITES, ((double)watch.ElapsedMilliseconds) / 1000f);
   }

   static bool CreateSitesInIIS(SiteCollection sites, string sitePrefix, int siteId, string dirRoot)
   {
      string siteName = sitePrefix + siteId;
      // site gets set to Poolname using the following format. Example: 'Site_POOL10'
      string poolName = POOLPREFIX + sitePrefix + siteId;

      try
      {
         Site site = sites.CreateElement();
         site.Id = siteId;
         site.SetAttributeValue("name", siteName);
         sites.Add(site);

         Application app = site.Applications.CreateElement();
         app.SetAttributeValue("path", "/");
         app.SetAttributeValue("applicationPool", poolName);
         site.Applications.Add(app);

         VirtualDirectory vdir = app.VirtualDirectories.CreateElement();
         vdir.SetAttributeValue("path", "/");
         vdir.SetAttributeValue("physicalPath", dirRoot + @"\" + siteName);

         app.VirtualDirectories.Add(vdir);

         Binding b = site.Bindings.CreateElement();
         b.SetAttributeValue("protocol", "http");
         b.SetAttributeValue("bindingInformation", ":80:" + siteName);
         site.Bindings.Add(b);
      }
      catch (Exception ex)
      {
         Console.WriteLine("Create site {0} failed. Reason: {1}", siteName, ex.Message);
         return false;
      }
      return true;
   }

   static bool CreateAppPoolInIIS(ServerManager mgr, string sitePrefix, int siteId)
   {
      string poolName = POOLPREFIX + sitePrefix + siteId;

      try
      {
         mgr.ApplicationPools.Add(poolName);
         ApplicationPool apppool = mgr.ApplicationPools[poolName];
         apppool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
      }

      catch (Exception ex)
      {
         Console.WriteLine("Create site {0} failed. Reason: {1}", poolName, ex.Message);
         return false;
      }
      return true;
   }
  }
}

要为每个站点设置唯一的临时编译目录,请使用以下代码:

using System;
using Microsoft.Web.Administration;
public class setASPNETCompilationDirectory
{
   static void Main()
   {
      ServerManager manager = new ServerManager();
      Configuration rootConfig = manager.GetWebConfiguration(new WebConfigurationMap(), null);
      ConfigurationSection section = rootConfig.GetSection("system.web/compilation");
      section.Attributes["tempDirectory"].Value = @"e:\inetpub\temp\temporary asp.net files\site1";
      section.SetMetadata("lockAttributes", "tempDirectory");
      manager.CommitChanges();
   }
}

使用 Active Directory 服务接口 (ADSI)

可以使用 Active Directory® 服务接口 (ADSI) 以编程方式用脚本或编译程序配置 IIS。 更改会立即生效,无需停止和启动服务器。

  • 优点
    使用 ADSI 配置大型站点或多台服务器快速高效。 ADSI 支持编写脚本,可以使用 ADSI 配置 IIS 4.0、IIS 5.0、IIS 5.1 和 IIS 6.0 以及 IIS7 及更高版本(已启用 IIS6 兼容模式),前提是使用错误检查来处理缺失的对象和属性。 还可以使用 ADSI 扩展 IIS 架构,但不建议这样做。
  • 缺点
    如果创建了站点或虚拟目录,或使用依赖其他属性的属性,则必须确保知道还需要创建和设置哪些支持属性。 仅当启用了 IIS 6 兼容模式时,ADSI 才可用于 IIS 7 及更高版本。 请注意,ADSI 的使用难度也很大。

使用 OLE 自动化

可以通过 Microsoft® JScript® 和 Microsoft® Visual Basic® Scripting Edition (VBScript) 来使用 OLE 自动化 (ProgId=Microsoft.ApplicationHost.WritableAdminManager)。

  • 优点
    配置大型站点或多台服务器快速高效。 OLE 自动化实际上比 Microsoft.Web.Administration 要快一些,而且也是可远程的。
  • 缺点
    您需要了解更低级别的 API 才能配置某些对象和属性。 需要 RPC 进行远程服务器配置。

使用管理基对象 (ABO)

使用 ABO 以编程方式通过使用 C、C++ 或 Microsoft® Visual Basic® 6.0 编写的已编译程序配置 IIS。

  • 优点
    此方法比使用 ADSI 或 WMI 更快速,因为 ADSI 和 WMI 提供程序是 ABO 的包装器。
  • 缺点
    如果创建了站点或虚拟目录,或使用依赖其他属性的属性,则必须确保知道还需要创建和设置哪些支持属性。
    ABO 不可编写脚本。 ABO 应用程序只能使用 C++ 或 Visual Basic 6.0 编写。
    由于 ABO 以最低级别访问 IIS,因此比 ADSI 或 WMI 更难使用,因为无法将多行 ABO 代码压缩为一个方法调用。 此外,没有可预防配置无效设置的安全措施。

注意

本文更新了 Walter Oliver 于 2007 年 12 月 2 日发布的“代码示例和脚本”中的文章。