作者: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 日发布的“代码示例和脚本”中的文章。