IIS

开始使用 IIS 7.0

Fergus Strachan

概览:

  • 在 Web 场环境中部署 IIS 7.0
  • 安全性和性能增强
  • 将 ASP.NET Web 应用程序从 IIS 6.0 迁移到 IIS 7.0
  • 将 PHP Web 应用程序迁移到 IIS 7.0

目录

准备、设置、测试
我的测试安装
IT 管理员获得的重要增强功能
IIS 体系结构
集成和经典模式
模块和功能
Web 应用程序迁移
总结

Microsoft 的 IIS 团队宣称 Internet 信息服务 (IIS) 7.0 是 IIS 史上最大的一个版本。此版本设置了新的标准、做出了根本性的改进并

引进了新功能来巩固 Web 环境。IIS 7.0(包含在 Windows Server® 2008 和 Windows Vista® SP1 中)已应用于 Microsoft.com,并且多家 Web 托管公司已开始向希望将现有的 Web 应用程序转到新 Web 服务器平台的 Web 设计人员和开发人员提供 IIS 7.0 托管服务。

在本文中,我将探讨对于 IT 专业人员而言最为重要的关键 IIS 7.0 增强功能,然后将详细介绍迁移 ASP.NET 和 PHP Web 应用程序。但首先,我想要简要介绍一下模拟基本生产环境的测试实验室。

这是一个重要的任务。在将 IIS 7.0 部署到生产服务器之前,您需要花费一些时间来在实验室环境中执行全面测试,从而确保 Web 应用程序能在新 Web 服务器上顺利运行。

准备、设置、测试

测试实验室包括运行 Windows Server 2003 和 IIS 6.0 的系统(用于托管 ASP.NET 应用程序),以及运行 Ubuntu 7.10 Linux 分发版和 Apache HTTP Server 2.2 的服务器(用于托管基于 PHP 的 Web 应用程序)。我的最终目标是在临时和生产系统上部署 Windows Server 2008,然后转换复杂的 Web 应用程序以将 IIS 6.0 和 Apache 实例替换成 IIS 7.0。

我有两个主要 Web 应用程序:DotNetNuke 4.7 和 osCommerce 3.0a4。DotNetNuke 是基于 ASP.NET 2.0 和 Microsoft® SQL Server® 的一个 Web 应用程序框架。另一应用程序 osCommerce 是构建于 PHP 和 MySQL 之上且功能完备的电子商务解决方案的最新 alpha 版本。现在,让我们将这些高级应用程序放入 IIS 7.0 中!

需要说明的是,比较软件版本、产品或平台并非我的目的所在。但是,在 Windows Server 2008 和 IIS 7.0 中包含了许多我应当指出的标准化优点。比如,管理复杂程度有所降低,并且可以最大限度减少运行的 Web 服务器总数。

图 1 提供了本文将用到的测试实验室的概述。如果要在自己的测试环境中遵循我的说明,随附材料中有所需软件组件以及详细的分步安装说明的链接(可从《TechNet 杂志》**网站的“代码下载”获取该随附材料)。

fig01.gif

图 1 用于部署 IIS 7.0 的测试环境(单击此图像可查看大图)

请注意,在我结束本文的撰写时,Microsoft 发布了一个命令行工具 (MSDeploy.exe) 来支持客户部署、同步以及将 Web 应用程序迁移到 IIS 6.0 和 7.0。建议您了解一下该工具。可在 go.microsoft.com/fwlink/?LinkId=118272 处的 Microsoft Web 部署团队博客上找到相关的详细信息。

我的测试安装

在撰写本文时,Windows Server 2008 仍为预发布版,因此我并未替换域控制器或数据库服务器上的 Windows Server 2003。如果使用 Windows Server 2008 的官方发布版本,您可能还希望考虑迁移您的 Active Directory® 基础结构。将 SQL Server® 2005 和 MySQL 数据库迁移到 SQL Server 2008 同样超出了本文的讨论范围。

我在阶段服务器上部署 SQL Server 2008 的主要原因是它比安装带有 Service Pack 2 的 SQL Server 2005 更方便。DotNetNuke 完全可与 SQL Server 2008 数据库一同运行。在 Windows Server 2008 上安装 MySQL 5.0 也非常直观明了,并无复杂之处。

虽然 Server Core 上提供有 IIS 7.0,但由于测试有一些特定要求,我并未使用 Server Core 安装。阶段服务器需要完整的安装,因为它是我的主要测试系统。此外,Server Core 上并无 Microsoft .NET Framework。

PHP 可在 Server Core 上正常运行,但由于我的目标是整合 ASP.NET 和 PHP 应用程序,因此不会选择使用 Server Core。在 Server Core 支持 .NET Framework 之前,您需要执行完整安装来支持 ASP.NET 应用程序。如需安装测试环境的详细分步指南,请阅读随附材料中的 01_install_testlab.htm 文件。

我选择全新安装 Windows Server 2008(而不是升级现有的服务器)。此外,全新安装更易于实施如图 2 所示的逐步迁移方案。基本策略是继续运行现有的 Web 场,直到所有相关的 Web 应用程序组件已在阶段服务器上测试成功并迁移到新的 IIS 7.0 Web 场中。

fig02.gif

图 2 逐步切换到 IIS 7.0(单击此图像可查看大图)

可选择一次性或逐步迁移所有现有的 Web 应用程序,具体取决于环境的复杂程度。对于每个 Web 应用程序或站点,在新的 Web 场上执行最终验收测试后,即可通过更改相关 DNS 记录将浏览器指向新 IIS 7.0 Web 场来实现切换。这种方式可将停机时间和服务中断降到最低。

IT 管理员获得的重要增强功能

《MSDN® 杂志》刊登了一篇由 Mike Volodarsky 撰写的题为“探索用于 Windows Vista 的 Web 服务器和更多内容”的优秀文章(网址为 msdn2.microsoft.com/magazine/cc163453.aspx),可通过该文章快速了解 IIS 7.0 中的改进。

另一不错的文章是 Microsoft.com 团队发表的名为“狗粮中的美味”的博客帖子(网址为 go.microsoft.com/fwlink/?LinkId=117436)。该帖子概述了团队成员最初的 IIS 7.0 体验。简单地说,他们评出了以下主要改进:

  1. 简洁安装。
  2. 更好的兼容性。
  3. 不再存在元数据库。
  4. 通过 UNC 共享中的 applicationHost.config 文件实现集中式配置。
  5. 通过应用程序目录中的 web.config 文件进行委派配置
  6. 改进了管理工具。
  7. 失败请求跟踪。
  8. 无需 URLScan 即可实现请求过滤。
  9. 通过 UNC 共享简化了内容同步可用性。
  10. 动态内容的输出缓存功能。

“简洁安装”毫无疑问是让人心动的。在博客上的帖子中,Microsoft.com 团队演示了如何利用单个命令行来部署 IIS 7.0 的所有功能(当然,或者仅是您需要的功能)。我非常希望通过使用图 3 中所示的命令行将这种方法合并到我的测试实验室安装指令中。

无可否认,该命令相当地长。(如果想要复制该命令,建议从《TechNet 杂志》**网站进行复制和粘贴,而不要手动重新键入。)尽管该命令将所有可用的模块都部署到 IIS 7.0 计算机上,但却不包括 PHP。IIS 7.0 并不包括 PHP,而且通过 Internet 下载和安装 Debian 数据包这一概念对于 Windows® 包管理程序 (pkgmgr.exe) 来说非常陌生。添加 Windows 自动安装工具包 (AIK)。

图 3 通过单个命令行部署 IIS 7.0 功能

start /w pkgmgr.exe /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;IIS-HttpRedirect;IIS-ApplicationDevelopment;IIS-ASPNET;IIS-NetFxExtensibility;IIS-ASP;IIS-CGI;IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-ServerSideIncludes;IIS-HealthAndDiagnostics;IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-ODBCLogging;IIS-Security;IIS-BasicAuthentication;IIS-WindowsAuthentication;IIS-DigestAuthentication;IIS-ClientCertificateMappingAuthentication;IIS-IISCertificateMappingAuthentication;IIS-URLAuthorization;IIS-RequestFiltering;IIS-IPSecurity;IIS-Performance;IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic;IIS-­WebServerManagementTools;IIS-ManagementConsole;IIS-ManagementScriptingTools;IIS-ManagementService;IIS-IIS6ManagementCompatibility;IIS-Metabase;IIS-WMICompatibility;IIS-LegacyScripts;IIS-LegacySnapIn;IIS-FTPPublishingService;IIS-FTPServer;IIS-FTPManagement;WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI

# Command provided by the Microsoft.com team (<a href=\"https://blogs.technet.com/mscom\" xmlns=\"http://www.w3.org/1999/xhtml\">blogs.technet.com/mscom</a>).

通过使用 AIK,可针对 Windows Server 2008 创建包含 IIS 7.0 和 PHP 5 的自定义安装 DVD。还可包含 MySQL、Web 应用程序文件以及部署中需要的所有其他组件。所有组件都可作为 Windows Server 2008 安装的一部分,从而可在所有 Web 服务器上统一应用自定义设置。此过程不需要使用命令行或编辑配置文件。

甚至可创建一个自定义 DVD 来执行完全无人参与安装。AIK 中包括用于创建 AutoUnattend.xml 文件的文档和工具,并且随后应将该文件放到 DVD 的根文件夹中。随附材料中的 Custom Image Deployment.htm 文件提供了分步说明。

许多管理员都认为兼容性也是一项重要的改进。在随后的操作过程中,我预计会遇到许多与 DotNetNuke 和 osCommerce 有关的兼容性问题,但转换到 IIS 7.0 的过程却相当轻松,尽管这两个 Web 应用程序都包括许多高级功能(如表单身份验证和搜索引擎友好的 URL)。

对于 DotNetNuke,向复杂 Web 场方案(在 64 位平台上共享 UNC 内容)的迁移完成得很顺利。几乎没遇到什么大问题。由于兼容性有所改进,大为节省了将 Web 应用程序转换为在 IIS 7.0 上运行所需的时间。

如果碰巧遇到与 Web 应用程序有关的兼容性问题,则内置诊断和跟踪支持这一新功能将迅速发挥功效。详细的诊断信息非常有意义,并且建议的解决方案非常有用并能实际奏效。

图 4 显示了以集成模式在 IIS 7.0 上运行 DotNetNuke 4. 7 时得到的诊断信息。在此示例中,共有三个选项(如“可尝试的方法”部分所示)。更改应用程序来支持集成模式可能是 DotNetNuke 开发人员的最佳选择。而忽略错误并不是个好主意。我喜欢第三种选择,即通过将 Web 应用程序切换到 Classic .NET AppPool 来启用经典模式,因为我希望不用修改 DotNetNuke 4.7 即可在 IIS 7.0 上运行它。

fig04.gif

图 4 以集成模式运行 DotNetNuke 时的诊断信息(单击此图像可查看大图)

IIS 体系结构

您可能很想知道什么是集成模式和经典模式,以及它们为什么会影响 ASP.NET 应用程序 (DotNetNuke) 而不影响 PHP 应用程序 (osCommerce)。要更好地理解这一点,您必须首先了解一下 IIS 7.0 的体系结构。以前的版本主要通过 ISAPI 扩展 (aspnet_isapi.dll) 将 ASP.NET 运行时集成到核心 Web 服务器当中。而 IIS 7.0 允许 ASP.NET 模块通过一个名为 ManagedEngine 的全局 HTTP 模块(它将 ASP.NET Support DLL (webengine.dll) 加载到 IIS 7.0 请求处理管道中)直接插入到核心 Web 服务器中。

本机模块使用 IIS Web 服务器核心 API 来在管道中注册特定事件,如 BeginRequest、Authenticate­Request、AuthorizeRequest 和 Execute­RequestHandler。ManagedEngine 还提供必要的支持来将 ASP.NET 模块集成到请求管道中。通过使用该新体系结构,IIS 7.0 可以在处理请求的过程中随时调用本机和 ASP.NET 模块,而不用考虑所请求的内容类型。

例如,让我们来看看 ASP.NET 用户身份验证。在 IIS 6.0 中,基于 ASP.NET 的 HTTP 模块可以注册 On­Authenticate 事件(如 Forms­Authentication.OnAuthenticate 和 Win­dows­Authentication.OnAuthenticate)以设置当前 HttpContext 中用户的身份。这种方法在 ASP.NET 运行时内部非常奏效,但您无法使用该 ASP.NET 代码来保护通过基于 PHP 的 Web 应用程序公开的资源。

根据其 scriptmap 配置,IIS 6.0 将 ASP.NET 内容类型的请求转发到 aspnet_isapi.dll,但它不会将 PHP 内容类型的请求转发到 ASP.NET 的 ISAPI 扩展。毕竟,ASP.NET 无法处理 PHP 代码,但它同样也意味着如果请求的是 PHP 页面,那 ASP.NET 身份验证代码将无法运行。因此,使用 IIS 6.0 时需复制身份验证逻辑,因为 PHP 应用程序必须实施自己的身份验证机制。

IIS 7.0 使用事件驱动型处理模型,该模型支持在请求管道中混合和匹配各个模块。IIS 7.0 还另行附带了受管 WindowsAuthentication 和 FormsAuthentication 模块,当请求管道触发 AuthenticateRequest 事件时,这些模块会启动 OnAuthenticate 事件。现在,可使用本机模块(如 Request­FilteringModule 或 IpRestrictionModule)处理 BeginRequest 事件以尽早地拒绝关键请求,然后运行 AuthenticateRequest 事件中的自定义 ASP.NET 身份验证代码并让 FastCgiModule 运行 Execute­RequestHandler 事件中的 PHP 脚本引擎 (php-cgi.exe) 来处理 PHP 页面。

这种集成体系结构使得 Web 开发人员不必复制代码来实现常见的业务逻辑。可使用自定义 ASP.NET 身份验证代码保护包括 PHP 应用程序在内的所有 IIS 资源。还可通过 ASP.NET 模块执行其他处理前和处理后任务,如 URL 重写、自定义跟踪和错误日志记录。

集成模式和经典模式

此新体系结构的副作用是可能需要应用程序开发人员更改现有 ASP.NET 应用程序的代码和配置,以确保该更改不会导致请求管道中发生模块冲突。但如果无法立即更改某个现有 Web 应用程序,则可在工作进程运行 Web 应用程序所用的应用程序池中启用经典模式。IIS 7.0 不会将 ManagedEngine 加载到经典模式的工作进程中,即,此时请求管道无法解析或调用 ASP.NET 模块。IIS 7.0 会激活大量基于 IsapiModule (aspnet_isapi.dll) 的 ISAPI 处理程序来按照类似 IIS 6.0 的方式处理 ASP.NET 内容类型。如果分析 applicationHost.config 文件(默认位于 %WinDir%\­System32\InetSrv\Config 文件夹中)system.web­Server 下的处理程序部分,您就会明白这种处理方式。

以搜索字符串 aspx 为例,您将找到一个指向 PageHandlerFactory-Integrated 的条目(根据设置 preCondition="integratedMode" 加载到集成模式的应用程序池工作进程中)以及指向 PageHandlerFactory-ISAPI-2.0 和 PageHandlerFactory-ISAPI-2.0-64 的其他条目(根据设置 preCondition="classicMode" 加载到经典模式的应用程序池工作进程中)。

由于管道模式是在应用程序池级别设置的,因此 IIS 7.0 可同时以集成模式和经典模式运行 Web 应用程序。并且,工作进程仅需在不同应用程序池中运行,但可托管在同一台服务器上。

请记住,集成模式和经典模式仅影响 IIS 7.0 将 ASP.NET 集成到请求管道的方式。这些管道模式不会直接影响 PHP 应用程序。无论使用的是集成模式还是经典模式,加载 FastCgiModule 和所有其他本机模块都不需要管道模式预处理。FastCGI 是在 IIS 7.0 上运行 PHP 脚本引擎的首选接口。如果不使用 FastCGI,也可通过 CGI 为 PHP 脚本引擎创建一个处理程序映射,或者可将 IsapiModule 与 PHP-ISAPI (php4isapi.dll) 结合使用。

但是,我认为这些 IIS 6.0 式的配置备用方法现已过时,因为 FastCGI 在性能和稳定性方面均提供了实质性改善。IIS 必须为每个 HTTP 请求初始化新的 CGI 进程,而 FastCGI 则针对多个请求重用 CGI 进程,因此 CGI 相对较慢。ISAPI 需要线程安全的 PHP,而这比运行非线程安全的 PHP 开销更大。

或许更为重要的一点是:线程安全版本中并未提供所有的 PHP 扩展,而使用 ISAPI 运行非线程安全的扩展并不是个好主意,因为它可能导致服务器出现稳定性问题。而 FastCGI 是一个与 CGI 类似的单并发环境。FastCGI 用于运行非线程安全的 PHP 时既稳定又快速,因此它显然是在 IIS 7.0 上运行 PHP 5 的最好方法。如果尚未准备好转换到 IIS 7.0,也可在 IIS 6.0 上使用它。

模块和功能

IIS 7.0 以高度模块化的体系结构(或者按照 IIS 开发人员的话来说,组件化的功能集)而著称。这对于希望使 IIS 7.0 的内存占用量和攻击面尽可能小的 Web 管理员来说是一个好消息。通过启用不同的模块甚至将标准模块替换成自定义模块,就可以完全控制 Web 服务器上的 IIS 7.0 功能。

要以集成模式或经典模式运行 ASP.NET 以及同一台服务器上的 PHP 应用程序,必须至少安装 Web 服务器角色和核心模块以支持请求处理、服务器配置、ASP.NET、ISAPI 和 CGI(它包括了 FastCGI 模块)。通过以下命令行即可实现:

start /w pkgmgr /iu:IIS-WebServerRole;
WAS-WindowsActivationService;WAS-ProcessModel;
WAS-ConfigurationAPI;IIS-ASPNET;
IIS-NetFxExtensibility;WAS-NetFxEnvironment;
IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-CGI

我通常更喜欢在阶段服务器上安装 IIS 7.0 及所有的可用选项,以确保所有组件和管理工具均可用于快速启动并运行 Web 应用程序。我的策略是先确保一切运转正常,然后通过卸载角色服务和禁用模块来缩小配置。当 Web 应用程序开始工作不正常时,我就把刚才卸载的角色服务或模块添加回去。

也可选择使用包管理器 (pkgmgr.exe) 或 IIS 7.0 命令行工具 (appcmd.exe),或者直接编辑 applicationHost.config 文件的 globalModules 部分,但我发现图形工具更为方便。请记住,有些模块(如 RequestFilteringModule 和 StaticCompressionModule)非常有用,尽管严格来说它们并非运行 Web 应用程序所必需的模块。如果卸载了应用程序池需要的模块,那么在访问 Web 应用程序时,您会收到一个 HTTP 错误(如图 5 所示)。

fig05.gif

图 5 由于缺少 IsapiModule,ASP.NET 应用程序无法在经典模式下运行(单击此图像可查看大图)

备注:最佳做法是,确保在所有 IIS 7.0 服务器上都安装和启用了相同的模块组。要确认已安装的组件,请转到 HKEY_LOCAL_MACHINE\Software\Microsoft\InetStp\Components\ 并检查注册表项。如果注册表项(如 NetFxEnvironment 或 CGI)的 REG_DWORD 值为 0000 0001,则表示已安装对应的组件。

Web 应用程序迁移

鉴于已掌握足够多的理论知识,现在就可以着手将一些 Web 应用程序迁移到 IIS 7.0了。如前所述,我的阶段服务器运行 IIS 7.0 的所有可用组件以及使用 FastCGI 注册的非线程安全 PHP 5。在开始之前,我需要询问以下几个基本问题:

  • Web 应用程序是否需要数据库管理系统(如 SQL Server 或 MySQL)?
  • 是否需要安装或配置其他组件(如 ODBC 连接、COM 对象或 SSL 证书)?
  • Web 应用程序是否需要特殊的服务帐户以及提升对文件共享和其他资源的本地或远程访问权限?
  • 某个平台专用功能的依赖关系是否在 IIS 7.0 上变得无法使用(例如依赖 Apache 模块来执行 URL 重写 (mod_rewrite))?

询问此类问题可有助于更快地将 Web 应用程序迁移到 IIS 7.0 上。例如,如果尝试从使用 mod_rewrite 的 Apache 2.2 迁移某个 PHP 应用程序(比如为了得到友好的搜索引擎或预防通过内联图像发起的带宽攻击),那么必须在 IIS 7.0 上部署兼容的自定义 URL 重写解决方案,才能避免出现问题。幸运地是,osCommerce 在 IIS 7.0 上不需要使用 mod_rewrite 功能,但某些搜索引擎优化数据包却可能会使用该功能。

既然已确定并在阶段服务器上安装了所需的其他组件,那么我已准备好启动并运行 Web 应用程序。同样,我还想问自己几个问题:

  • 可使用哪些最简单的配置来支持 Web 应用程序?
  • 生产环境中目前使用的是些什么配置?
  • 我能否在新平台上优化 Web 应用程序配置?
  • 能够使 Web 应用程序在理想配置下正常运行的最小角色服务和模块集合是什么?

以最简单的配置运行 Web 应用程序是验证其是否有效的一种快速方法。如果一切正常,就可以将类似配置应用到现有生产环境并将生产数据导入到测试数据库中。当然,某些问题可能仅会在高级配置时才会浮现出来。

在测试实验室中镜像生产配置时,也可能找到改进的机会。将 applicationHost.config 文件放在 UNC 共享中很适合集中多台 Web 服务器的配置。要通过冗余和内容同步来提高容错能力,可考虑实施分布式文件系统 (DFS) 复制(它是一种 Windows Server 2003 R2 和 Windows Server 2008 中提供的基于状态的多主机复制引擎)。还可通过将 Web 应用程序的内容文件放在 UNC 共享上来最小化 Web 前端的存储需求。

其他优化方法可能会涉及到安全性或动态缓存。我并未在测试实验室中考虑安全性和性能方面的优化,因为它超出了本文的讨论范畴。我也没有配置 DFS 来避免安装更多服务器。随附材料中的分步说明简要示范了如何在 UNC 共享上托管 applicationHost.config 文件和 Web 内容。图 6 说明了如何使用 DFS 实现基于 UNC 的 Web 场。

fig06.gif

图 6 将 applicationHost.config 文件和 Web 内容放在 UNC 共享上的 Web 场部署(单击此图像可查看大图)

结束语

IIS 7.0 是一个令人印象深刻的 Web 服务器平台。它的特色是重新设计了核心体系结构,同时几乎 100% 地向后兼容 IIS 6.0。它应该能够做到无需修改即可运行大部分现有的 ASP.NET Web 应用程序。但由于体系结构的更改较大,因此很可能会遇到兼容性问题。

无论是将 ASP.NET 还是 PHP Web 应用程序迁移到 IIS 7.0,最好都采用分步式方法,并且注重正确的规划、准备、测试以及记录代码和配置更改。

IIS 7.0 会令工作物有所值。它在安全性、性能、可配置性和灵活性等方面都进行了许多改进。要讨论完所有这些内容可能需要编写一本书。基于 UNC 共享的集中式配置和内容共享、通过应用程序目录中的 web.config 文件实现委派配置、改进的管理工具、详细的诊断信息和失败请求跟踪以及动态输出缓存都是赢得 Web 管理员欢心的出色方法。

在请求处理管道中混合本机和托管模块的功能可使 ASP.NET 开发人员受益颇多。并且,IIS 7.0 上的 FastCGI 在性能和稳定性方面的改进令 PHP 应用程序开发人员倍感欣慰。

而且,还有一项能够帮助 IT 专业人员成功应用 IIS 7.0 的重要工具:那就是 Microsoft IIS 社区门户网站 (www.iis.net)。它包含您需要的所有信息,包括有关新体系结构的详细说明文章、向 C++ 和 ASP.NET 开发人员展示如何创建 IIS 7.0 模块的源代码以及用于启动并运行 PHP 应用程序的分步说明。您肯定会用到该网站。它是为您回答 IIS 问题的首选途径。

Fergus Strachan 是 Maestra Ltd London 的创始人和董事,该公司是一家专门从事 IT 基础结构设计和项目管理支持的咨询公司,向英国的国际银行和教育机构提供服务。他撰写过多篇有关 Microsoft 服务器技术的文章,并且是**《Integrating ISA Server 2006 with Microsoft Exchange 2007》一书的作者。还是《Microsoft Exchange Server 2003 Resource Kit》**的合著者。

© 2008 Microsoft Corporation 和 CMP Media, LLC。保留所有权利;未经允许不得复制本文的部分或全部内容。