8 月 2008 8 月 2008
SQL Server: 高效维护数据库的关键技巧
很多时候，负责数据库的人员并不是经过专门训练的数据库管理员。他们缺乏维护其数据库的相应培训和知识，因而问题就开始显现出来。这样的人员需要数据库维护最佳实践方面的速成课，本文为他们介绍了必备的基础知识。 Paul S. Randal
Windows 管理: 为服务器把脉
如果用户抱怨服务器运行速度过慢，您是否知道应该如何诊断问题？“性能监视器”可能是这方面不可或缺的工具，因为它具有许多诊断功能。概要了解一些关键指示器，以便能够使用它们来诊断使服务器速度减慢的各种常见瓶颈问题。 Steven Choy
System Center: System Center Operations Manager 中的 Windows PowerShell
Windows PowerShell 已集成到 System Center Operations Manager 2007 中，它提供了一种强大的方法来执行和自动化常见的管理任务。大致了解如何使用 OpsMgr 中的 Windows PowerShell 来执行常规维护、管理代理等任务。 Marco Shaw
Internet 信息服务: 扩展 ASP.NET 应用程序：经验教训
成功扩展 ASP.NET 应用程序的关键是让开发人员和网络管理员在应用程序的生命周期伊始就展开协作。找出哪些因素是扩展应用程序所必须的，并了解这种协作如何帮助确保应用程序按预期运行。 Richard Campbell
Columns
编辑寄语: 现场直播 Tech•Ed: | 读者来信: 读者心声: | 工具箱: 面向 IT 专业人员的新产品:
SQL 问题与解答: 分区、一致性检查以及其他更多内容: Paul Randal 将回答您在 SQL Server 方面的问题，为您介绍如何对超大的数据库执行一致性检查和其他维护任务， 如何处理突发升级等。Paul S. Randal | 实用工具特别推荐: Windows Installer 清理实用工具: 在尝试更新或卸载某个应用程序时，残余的 Windows Installer 配置信息可能会导致出现问题。您可以使用 Windows Installer 清理实用工具解决这一问题，它能帮您删除应用程序的 Windows Installer 信息并重新安装应用程序。Lance Whitney | 深入剖析 SharePoint: 消息传递集成故障排除: 将 SharePoint 集成到一个安全的消息传递环境并非易事，但它给生产效率所带来的积极影响却值得我们为此付出努力。本文中的指导帮助您排除设置环境时出现的问题。Pav Cherny
Windows PowerShell: 远程管理 2.0 版快速浏览: Windows PowerShell 2.0 即将推出，而最新的 CTP 提供了一些不错的新功能。本文介绍了 Windows PowerShell 2.0 CTP2 中远程作业一项最令人心仪的新功能。Don Jones | 您好，脚本专家！: 使用快速通道: 在 Windows Vista 中，用来打开文件打开对话框的 UserAccounts.CommonDialog ActiveX 控件已不再存在。本文介绍了如何使用 Visual Basic 速成版来解决此问题。Microsoft 脚本专家 | 桌面文件: Windows 部署服务 101: 探索不同版本的 Windows 部署服务，了解如何捕获自定义 OS 映像并找出执行更高程度自动化安装所需的内容。Wes Miller
安全观察: 密码和信用卡，第 2 部分: 此系列文章共分三个部分，在最后一部分中，Jesper Johansson 将介绍软件供应商、安全套件以及营销措施如何阻碍真正的安全努力，并且还会警告我们这些做法将如何导致技术安全体系的崩溃。Jesper M. Johansson | 可持续计算: 筛选漂绿: 了解您的功率消耗对于管理 IT 基础结构而言是不可或缺的一部分。掌握在自身环境中监视功率的部署策略，从而更好地了解您整个组织中设备的功率消耗情况。Dave Ohara | 领域备注: IMAP 拯救世界: 你是否将电子邮件保存在多个不同的地方、以不同格式保存或保存在不同的操作系统上？Dara Korrati 为您讲述如何使用 IMAP4 从一个位置访问所有的邮件。R'ykandar Korra'ti
Windows 机密: 昔日的王者: Raymond 将介绍曾经辉煌一时的 Alpha AXP 系统如何退出历史舞台以及如何帮助开发新一代的 64 位系统。Raymond Chen


SQL Server
高效维护数据库的关键技巧
Paul S. Randal
概览：
  • 管理数据和事务日志文件
  • 清除索引碎片
  • 确保统计数据准确、最新
  • 检测遭到破坏的数据库页
  • 建立有效的备份策略

目录
数据和日志文件管理
索引碎片
统计数据
损坏检测
备份
总结
在一周之内多次有人向我征求高效维护生产数据库的建议。有时问题来自 DBA，他们正在实施新的解决方案，希望得到帮助
对维护进行精细调整适合其新数据库的特点。但更为常见的情况是：提问的人不是专业 DBA，而是由于某种原因拥有数据库并承担相关责任的人员。我喜欢将这种角色称为“非自愿 DBA”。本文重点是为所有非自愿 DBA 提供数据库维护最佳实践的入门知识。
在 IT 世界里，大多数任务和程序都没有一个简单、通用的解决方案可以高效维护数据库，但却有一些必须受到重视的关键领域。我所关心的五大重要领域是（没有任何特殊的重要性顺序）：
  • 数据和日志文件管理
  • 索引碎片
  • 统计数据
  • 损坏检测
  • 备份
一个未经维护（或维护不良）的数据库可能会在其中的一个或多个领域内引发问题，最终可能导致应用程序性能欠佳，甚至是停机以及丢失数据。
在本文中，我将说明这些问题很重要的原因并向您展示一些缓解这些问题的简单方法。我将以 SQL Server® 2005 为基础进行说明，但我还会着重指出您将会在 SQL Server 2000 和即将发布的 SQL Server 2008 中发现的主要差别。

数据和日志文件管理
我始终建议在接管数据库时检查的第一个领域涉及到与数据和（事务）日志文件管理相关的设置。具体地说，您应确保：
  • 数据和日志文件彼此分开，而且还与其他所有内容相互隔离
  • 自动增长已正确配置
  • 即时文件初始化已配置
  • 自动缩减未启用而且缩减不是任何维护计划的内容
当数据和日志文件（理想情况下应分别位于不同的卷中）与其他任何创建或扩展文件的应用程序共享一个卷时，可能存在文件碎片。在数据文件中，过多的文件碎片可能是导致查询（特别是扫描非常多数据的查询）效果不佳的一个因素。在日志文件中，它可能会对性能产生相当大的影响，尤其是在自动增长设置为需要增加每个文件的大小时，增量很小的情形。
日志文件在内部被划分为多个称为“虚拟日志文件”(VLF) 的片段，而且日志文件（我在这里使用单数是因为拥有多个日志文件并没有任何好处，每个数据库只应有一个日志文件）内的碎片越多，VLF 就越多。一个日志文件具有多个（比方说，200 个）VLF 后，与日志有关的操作（如为事务性复制/回滚而读取日志）、日志备份乃至 SQL Server 2000 中的触发器（触发器的实现已在 SQL Server 2005 中更改为行版本框架，而不是事务日志）可能会对性能产生负面影响。
调整数据和日志文件大小的最佳做法是创建它们时使用适当的初始大小。对于数据文件，初始大小应考虑短期内向数据库中添加其他数据的可能性。例如，如果数据的初始大小为 50GB，但您知道在接下来的六个月内将再添加 50GB 的数据，那么应创建 100GB 的数据文件，而不是多次将其增大以达到该大小。
对于日志文件而言要更复杂一些，您需要多考虑一些因素，例如事务大小（长时间运行事务在完成之前无法从日志中清除）以及日志备份频率（因为这将删除日志的非活动部分）。有关详细信息，请参阅我的妻子 Kimberly Tripp 编写的一篇很受欢迎的博客文章提高事务日志吞吐量的 8 个步骤，它发表在 SQLskills.com 上。
设置一旦完成，应不时监视文件大小，并在每一天的适当时间先行手动增加其大小。为以防万一，应保留自动增长，这样文件即使在发生一些异常事件的情况下仍可以完成所需的增长。反对将文件管理完全保留为自动增长的逻辑是步长极小的自动增长会导致文件碎片，而且自动增长会是一个耗时的过程，它可能会多次突然停止应用程序的工作。
应将自动增长大小设置为一个具体值，而不是一个百分比，以约束执行自动增长（如果发生）所需的时间和空间。例如，您可能希望将一个 100GB 的数据文件的自动增长大小设置为固定值 5GB，而不是（比方说）10%。这意味着无论文件每次变得多大，它均将按 5GB 进行增长，而不是一个持续增长的数量（10GB、11GB、12GB 等）。
当事务日志增长时（手动或自动增长），它将始终被初始化为零。数据文件在 SQL Server 2000 中具有同一默认行为，但从 SQL Server 2005 开始，您可以启用即时文件初始化，它会跳过零初始化文件，因此增长和自动增长会保持同步。所有版本的 SQL Server 中都提供了这一功能，这一点与正常的观点恰恰相佐。如欲了解详细信息，请在 SQL Server 2005 或 SQL Server 2008 的联机丛书索引中输入“即时文件初始化”。
最后，应注意不要以任何方式启用缩减。缩减可用于减小数据或日志文件的大小，但它是一个干扰很大、极耗资源的过程，会导致数据文件中产生大量的逻辑扫描碎片（详细信息请参见下文），并导致性能欠佳。我更改了 SQL Server 2005 联机丛书中的缩减条目，加入了一个警告，提醒注意此影响。但在特殊情况下，允许手动缩减单个数据和日志文件。
视频
观看 Paul Randal 演示缩减和自动缩减如何导致数据库发生严重的碎片问题。

自动缩减的后果极为严重，因为它每 30 分钟就会在背景中启动一次，并会尝试缩减自动缩减数据库选项被设置为 true 的数据库。从某种程度讲，它是一个无法预见的过程，因为它仅缩减拥有 25% 以上可用空间的数据库。自动缩减占用大量资源，会产生碎片并导致性能下降，因此在任何情况下都不是一个好计划。您应始终通过以下方式关闭自动缩减：
ALTER DATABASE MyDatabase SET AUTO_SHRINK OFF;
包含手动数据库缩减命令的定期维护计划几乎会产生同样糟糕的结果。如果您发现您的数据库在维护计划将其缩减后持续增长，原因在于数据库运行需要该空间。
最好的做法是允许数据库增长到稳定的大小，尽量避免运行缩减。您可以在我原来的 MSDN® 博客（位于 blogs.msdn.com/sqlserverstorageengine/archive/tags/Shrink/default.aspx）中找到有关使用缩减的缺点的详细信息，其中还有对 SQL Server 2005 中新算法的一些评论。

索引碎片
除了文件系统级和日志文件内的碎片以外，数据文件内存储表格和索引数据的结构中也可能存在碎片。数据文件内可能出现两种基本类型的碎片：
  • 单个数据和索引页内的碎片（有时称为内部碎片）
  • 由页面组成的索引或表格结构内的碎片（称为逻辑扫描碎片和扩展盘区扫描碎片）
内部碎片是页面中存在大量空白区域的位置。如图 1 所示，数据库中的每个页面大小为 8KB，页眉为 96 字节；因此，一个页面可以存储大约 8096 字节的表格或索引数据（我的博客 sqlskills.com/blogs/paul 有“深入了解存储引擎”一节，其中介绍了数据和行结构的特定表格和索引内部机制）。如果每个表格或索引记录超过页面大小的一半，可能会出现空白空间，因为每个页面只能存储一个记录。这可能很难或无法更正，因为它要求更改表格或索引架构，例如，将索引键更改为像 GUID 一样不会引发随机插入点。
图 1 数据库页的结构（单击图像可查看大图）
更常见的是，内部碎片源于数据修改（如插入、更新和删除），这可能会在页面中留下空白空间。管理不善的填充因子也可能会产生碎片；有关详细信息，请参阅“联机丛书”。根据表格/索引架构和应用程序的特征，此空白空间在其创建后可能就不再使用，导致数据库中的不可用空间量持续增长。
例如，我们来看一下一个 1 亿行表格，其中平均记录大小为 400 字节。后来，应用程序的数据修改模式为每个页面留下了平均 2800 字节的空白空间。该表格所需的总空间为 59GB，计算方法为 8096-2800 / 400 = 13 个记录/8KB 页面，然后将 1 亿除以 13 便可获得页面数。如果没有空间浪费，那么每个页面刚好容纳 20 条记录，所需的总空间下降至 38GB。这是多么大的节省！
如数据/索引页中出现空间浪费，可能导致存储同样数量的数据需要更多的页面。这不仅会占用更多的磁盘空间，还意味着查询需要执行更多的 I/O 才能读取同样数量的数据。所有这些多出的页面在数据缓存中占用了更多空间，因而占用了更多的服务器内存。
逻辑扫描碎片是由称为页面分隔的操作而引发的。当必须在特定索引页（根据索引键定义）中插入记录但页面中并没有足够的空间来容纳所插入的数据时，便会发生这种情况。该页面会被分割一半，大约 50% 的记录被移到新分配的页面。通常，这一新页面实际上并不与旧页面相邻，因此，被称为零碎的页面。扩展盘区扫描碎片在概念上与此类似。表格/索引结构内的碎片会影响 SQL Server 执行有效扫描的能力，无论是对整个表格/索引进行扫描还是按查询 WHERE 子句（例如，SELECT * FROM MyTable WHERE Column1 > 100 AND Column1 < 4000）进行扫描都会受到影响。
图 2 显示的新建索引页填充率是 100%，没有碎片，这些页面完全被充满，而且页面的物理顺序与逻辑顺序相符。图 3 显示了在随机插入/更新/删除之后出现的碎片。
图 2 不带碎片的新建索引页；页面被完全填充（单击图像可查看大图）
图 3 随机插入、更新和删除之后出现内部和逻辑扫描碎片的索引页（单击图像可查看大图）
有时可以通过更改表格/索引架构来防止碎片，但正如我前面所提到的，这可能很难或根本无法实现。如果预防并不是办法，可以想办法在碎片产生后将其删除，具体来讲，是重新生成或重新组织索引。
重新生成索引涉及创建索引的新副本（有效压缩且尽可能连续），然后丢弃旧的零碎副本。在 SQL Server 删除旧的索引副本之前创建新副本时，在数据文件内所需的可用空间大致相当于此索引的大小。在 SQL Server 2000 中重新生成索引始终都是脱机进行的。在 SQL Server 2005 Enterprise Edition 中，索引重新生成可以联机进行，但有几个限制。而重新组织使用原位算法对索引进行压缩并整理碎片；它运行只需要 8KB 的额外空间，而且始终是联机运行的。实际上，在 SQL Server 2000 中，我专门编写了索引重新组织代码，用于替代重新生成索引，它的优点是联机且节省空间。
在 SQL Server 2005 中，用于调查的命令为 ALTER INDEX …… REBUILD 用于重新生成索引，ALTER INDEX … REORGANIZE 用于重新组织索引。此语法分别取代了 SQL Server 2000 中的命令 DBCC DBREINDEX 和 DBCC INDEXDEFRAG。
这些方法之间有许多种权衡选择，例如，所生成的事务记录量、所需的数据库可用空间量以及中断进程是否不会丢失数据等。您可以在 microsoft.com/technet/prodtechnol/sql/2000/maintain/ss2kidbp.mspx 上找到一份白皮书，其中介绍了这些权衡选择以及更多信息。虽然白皮书内容是根据 SQL Server 2000 编写的，但其中的概念向后续版本的过渡性很好。
一些人只是选择每晚或每周重新生成或重新组织所有索引（例如，使用维护计划选项），而不是找出哪些索引被分割为碎片以及删除碎片是否会带来任何好处。对于那些只是希望不费多少气力就可适当放置内容的非自愿 DBA 来说，这是一个不错的解决方案，但请注意：对于一些资源非常珍贵的大型数据库或系统来说，它可是一个非常糟糕的选择。
更好的方法包括使用 DMV sys.dm_db_index_physical_stats（或 SQL Server 2000 中的 DBCC SHOWCONTIG）来定期确定哪些索引被分割为碎片，然后选择是否以及如何对其进行操作。本白皮书还介绍了对这些更有针对性的选项的使用。此外，您还可以看到一些进行这种筛选的示例代码，即 SQL Server 2005 联机丛书 DMV sys.dm_db_index_physical_stats 条目的示例 D (msdn.microsoft.com/library/ms188917) 或 SQL Server 2000 以及更新版本联机丛书 DBCC SHOWCONTIG 条目的示例 E (msdn.microsoft.com/library/aa258803)。
无论您使用哪种方法，定期调查并修复碎片都是非常明智的做法。
查询处理器是 SQL Server 的一个部件，用于决定应如何执行查询，具体来说，是使用哪些表格和索引以及对其执行哪些操作才能获得所需的结果；它称为查询计划。此决策制定过程所需的一些最重要的信息就是统计数据，它们说明表格或索引内各个列的数据值分步情况。很明显，统计数据必须要准确而且保持最新，才能为查询处理器提供帮助，否则可能会导致查询计划性能不佳。
统计数据是通过读取表格/索引数据并确定相关列的数据分布而生成的。可以通过扫描特定列的所有数据值（全面扫描）构建统计数据，也可以根据用户指定的数据百分比（采样扫描）建立统计数据。如果列中各值的分布非常均匀，那么采样扫描就应该足以能满足要求，与全面扫描相比，这种方式会使统计数据的创建和更新更快。
请注意，可通过打开 AUTO_CREATE_STATISTICS 和 AUTO_UPDATE_STATISTICS 数据库选项自动创建和维护统计数据，如图 4 所示。这些选项默认情况下是打开的，但如果您只是继承了数据库，请进行检查加以确认。有时统计数据可能已过时，在这种情况下可以通过对特定的统计数据集使用 UPDATE STATISTICS 操作手动更新它们。或者，可以使用 sp_updatestats 存储过程，该过程会更新所有过时的统计数据（在 SQL Server 2000 中，sp_updatestats 更新所有统计数据，无论期限为何）。
图 4 通过 SQL Server Management Studio 更改数据库设置（单击图像可查看大图）
如果您想要在定期维护计划中更新统计数据，有一个问题您应当注意。UPDATE STATISTICS 和 sp_updatestats 均默认使用先前指定的采样级（如果有），这可能达不到全面扫描的效果。索引重新生成会自动使用全面扫描更新统计数据。 如果您在重新生成索引之后手动更新统计数据，最后得到的统计数据可能不太准确！如果来自手动更新的采样扫描覆盖通过索引重新生成而产生的全面扫描，可能会发生这种情况。而另一方面，重新组织索引根本不更新统计数据。
同样，许多人的维护计划是在重新生成所有索引之前或之后的某个时刻更新所有统计数据，因此可能不知道得到的是不太准确的统计数据。如果您经常做出的选择只是重新生成所有索引，这也会处理统计数据。如果您选择了更为复杂的方式，其中涉及删除碎片，您也应该执行此操作以维护统计数据。以下是我的一些建议：
  • 分析索引并确定要对哪些索引进行操作以及如何删除碎片。
  • 对于尚未重新生成的所有索引，更新统计数据。
  • 更新所有非索引列的统计数据。
有关统计数据的详细信息，请参阅白皮书“® SQL Server 2005 中的查询优化器所使用的统计信息”(microsoft.com/technet/prodtechnol/sql/2005/qrystats.mspx)。

损坏检测
我已经介绍了与性能相关的维护。现在我想换一项内容，介绍一下损坏检测与缓解。
您所管理的数据库一定会包含有用的信息，那么您如何确保数据在出现灾难时没有损坏或可以恢复呢？详细论述完整的灾难恢复和高可用性策略超出了本文的范围，但可以介绍一些简单的操作。
绝大多数的损坏是由“硬件”引起的。为什么我用引号将其引起来呢？因为此处的硬件实际上是指“SQL Server 下属 I/O 子系统中的某些内容”。I/O 子系统由操作系统、文件系统驱动程序、设备驱动程序、RAID 控制器、电缆、网络以及物理磁盘驱动器等组成。有许多地方确实会发生问题。
一个最常见的问题是当发生电源故障时磁盘驱动器正在写出数据库页。如果驱动器无法在电源耗尽之前完成写操作（或者写操作已缓存，但没有足够的备用电池来刷新驱动器的缓存），就可能在磁盘上产生不完整的页面映像。因为 8KB 数据库页实际上由 16 个连续的 512 字节扇区组成，所以这种情况可能会发生。不完整的写操作可能写出新页面中的一些扇区，但也会留下上一页面映像中的一些扇区。这种情况称为破损页。如果发生了这一情况，应如何检测呢？
SQL Server 提供了一种用于检测此情况的机制。它包括存储该页面每个扇区的几位并在其位置编写特定的模式（这恰好是在页面被写入磁盘之前发生的）。如果重新读取页面时此模式有变化，SQL Server 便会知道该页面已“破损”并引发错误。
在 SQL Server 2005 及后续版本中，提供了一种更加全面的机制，称为页面校验和，可以检查页中的任何损坏。这包括在写出页面之前编写整页校验和，然后在重新读取该页时对其进行检测，就象检测破损页一样。在启用页面校验和之后，必须将页读入缓冲池，以某种方式进行更改，然后在其受页面校验和保护之前将其重新写出到磁盘。
因此，最好的做法是为 SQL Server 2005 之后的版本启用页面校验和，为 SQL Server 2000 启用破损页检测。要启用页面校验和，请使用：
ALTER DATABASE MyDatabase SET PAGE_VERIFY CHECKSUM;
要为 SQL Server 2000 启用破损页检测，请使用：
ALTER DATABASE MyDatabase SET TORN_PAGE_DETECTION ON;
通过这些机制，您可以在某个页面出现损坏时进行检测，但只能在读取页面时进行。如何能够便于强制读取所有分配的页面？执行此操作（以及查找其他任何类型的损坏）的最好方法是使用 DBCC CHECKDB 命令。无论指定的选项为何，此命令始终都会读取数据库中的所有页面，从而导致验证所有页面校验和或破损页检测。您还应该设置警报，这样您就可了解用户在运行查询时何时遇到了损坏问题。您可以使用 24 个严重性错误警报得到上述所有问题的通知（图 5）。
图 5 为所有 24 个严重性错误设置警报（单击图像可查看大图）
因此，另一种最佳做法是定期对数据库运行 DBCC CHECKDB 以验证其完整性。此命令有许多形式，其运行频率也有很多说法。遗憾的是，还没有任何对此做介绍的白皮书。但是，因为 DBCC CHECKDB 是我为 SQL Server 2005 编写的主要代码段，因此我已在博客中对此做了详尽的说明。请参阅我博客中的 "CHECKDB From Every Angle" (sqlskills.com/blogs/paul)，里面有许多有关一致性检查、最佳实践以及方法建议的精深文章。对于非自愿 DBA，一条经验法则是在每次进行完整数据库备份时都运行 DBCC CHECKDB（更多相关信息请参见下文）。我建议运行以下命令：
DBCC CHECKDB ('MyDatabase') WITH NO_INFOMSGS,
  ALL_ERRORMSGS;
如果此命令有任何输出，表明 DBCC 已在数据库中发现了一些损坏。随之而来的就是如果 DBCC CHECKDB 发现了任何损坏应如何处理。这时就轮到备份出场了。
当发生损坏或其他灾难时，最有效的恢复方法是从备份还原数据库。此方法假定您第一时间进行了备份，而且这些备份本身没有损坏。人们经常想知道在其没有做任何备份的情况下如何让严重损坏的数据库重新运行起来。如果某种形式的数据丢失对您的业务逻辑和关系数据完整性造成了严重破坏，这一点根本做不到。
因此，完全有理由主张进行定期备份。使用备份和还原的细节远远超出了本文的范围，但我可以简要介绍一些如何建立备份策略的基础知识。
首先，应定期进行完整数据库备份。这会为您提供一个之后还原可以达到的时间点。可以使用 BACKUP DATABASE 命令进行完整数据库备份。相关示例请参阅“联机丛书”。若要增加保护，可以使用 WITH CHECKSUM 选项，它会验证所读取页的页面校验和（如果有）并计算整个备份的校验和。您应选择一个频率，它会反映您的业务能容忍的数据或工作丢失量。例如，每天进行一次完整数据库备份，意味着在发生灾难的情况下您最多可能丢失一天的数据。如果您仅使用完整数据库备份，应采用 SIMPLE 恢复模型（通常称为恢复模式），以避免与事务日志增长管理相关的复杂性。
其次，始终保留几天的备份，如果发生了损坏，使用几天之前的备份也要好于根本没有备份。您还应使用 RESTORE WITH VERIFYONLY 命令验证备份的完整性（仍请参阅“联机丛书”）。如果您在创建备份时使用了 WITH CHECKSUM 选项，运行验证命令将检查备份校验和是否仍然有效，并重新检查备份内的所有页面校验和。
第三，如果每日完整数据库备份不满足业务所能承受的最大数据/工作丢失量，您可试用差异数据库备份。差异数据库备份以完整数据库备份为基础，并包含自上次完整数据库备份后所有更改的记录（一个常见误解是差异备份是增量备份，其实不然）。一个示例策略是采用每日完整数据库备份，并每四个小时进行一次差异数据库备份。差异备份额外提供了一个时间点恢复选项。如果您仅使用完整数据库备份和差异数据库备份，仍应使用 SIMPLE 恢复模型。
最后，可恢复性最终涉及的是使用日志备份。它们仅在 FULL（或 BULK_LOGGED）恢复模型中可用，提供了自上次日志备份后所生成的所有日志记录的备份。使用定期完整数据库（也可能是差异数据库）备份维护一组日志备份会提供无限数量的恢复目标时间点（包括最新的恢复）。需要权衡的是事务日志将继续增长，直到通过日志备份将其释放。此处的示例策略将每天进行完整数据库备份，每四个小时进行一次差异数据库备份并在每半小时进行一次日志备份。
决定备份策略并对其进行设置可能会相当复杂。最起码，您应定期进行完整数据库备份，以确保您至少拥有一个可从中恢复的时间点。
正如您所看到的，要确保数据库保持良好状况并可供使用，必须要完成几项任务。以下是我制订的最终检查表，适合接管数据库的非自愿 DBA：
  • 删除多余的事务日志文件碎片。
  • 正确设置自动增长。
  • 关闭所有计划的缩减操作。
  • 打开即时文件初始化。
  • 定期检测并删除索引碎片。
  • 打开 AUTO_CREATE_STATISTICS 和 AUTO_UPDATE_STATISTICS，并定期更新统计数据。
  • 启动页面校验和（或者至少在 SQL Server 2000 上启动破损页检测）。
  • 定期运行 DBCC CHECKDB。
  • 定期进行完整数据库备份以及用于时间点恢复的差异和日志备份。
我在本文中给出了 T-SQL 命令，但您也可以利用 Management Studio 完成诸多操作。希望我的建议能帮您提高数据库的维护效率。如果您有任何反馈或问题，请发送电子邮件至 paul@sqlskills.com。

Paul S. Randal 是 SQLskills.com 的常务董事，也是 SQL Server MVP。从 1999 年到 2007 年，他一直在 Microsoft 的 SQL Server 存储引擎团队工作。Paul 是灾难恢复、高可用性和数据库维护方面的专家。他的博客地址是 SQLskills.com/blogs/paul。

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


Windows 管理
为服务器把脉
Steven Choy
概览：
  • 自定义性能监视器
  • 测量对象和测量频率指南
  • 关键计数器和查找对象概述

目录
使结果更具可读性
测量对象和测量时间
硬盘瓶颈
内存瓶颈
﻿处理器瓶颈
网络瓶颈
进程瓶颈
结束语
假如您周一早晨刚到办公室就遇到一位心急如焚的用户抱怨自己的服务器运行速度太慢。您会如何着手帮助他？性能
监视器是 Windows® 中内置的一款非常便利的工具，可帮助您诊断有关性能的问题。
要使用“性能监视器”，您可以在命令提示符下键入 perfmon，或从“管理工具”菜单中选择“性能”或“可靠性和性能监视器”（在 Windows Vista® 和 Windows Server® 2008 中）。要添加需要监视的性能计数器和对象，只需单击加号并从众多可能的选项中进行选择即可。
那么该如何测量服务器的脉搏呢？共有超过 60 个基本性能对象，每个对象又包含多个计数器。在本文中，我将介绍那些能够反映服务器最重要征兆的计数器，还将说明 Microsoft® 服务支持工程师在排除与性能相关的故障时最常使用的典型采样间隔。
当然，在故障排除时需要有一个基准来提供关键参考点。由于服务器负载取决于业务需求并且随着业务周期的不同而随时变化，因此必须根据指定期间内的常规工作负载建立一个基准。这将允许您据此观察其变更并确定其趋势。

使结果更具可读性
在对那些代表着最重要的服务器征兆的计数器进行深入分析之前，我首先向您介绍两个小技巧，它们可以帮助您更轻松地使用“性能监视器”来测量那些重要的服务器征兆。请注意，在 Windows Vista 和 Windows Server 2008 中用不到这些技巧；但如果在较早版本的 Windows 中运行“性能监视器”，那么这两个调整工具就可以派上大用场。
第一个技巧是，您可以删除会对趋势线图形视图产生不利影响的所有示例干扰点。在 Windows Vista 和 Windows Server 2008 中，“性能监视器”最多可在图形视图中显示 1000 个数据点。但在先前版本的 Windows 中，最多只显示 100 个数据点。如果超过 100 个，“性能监视器”将把数据点“装进桶中”。一条竖直线代表一个桶，表示桶中包括的示例点的最小值、平均值和最大值。
如图 1 中的图形所示，当同时显示如此多的数据时，一般很难发现趋势线。图 2 中的图形显示的是关闭了所有无关的可视信息后的情形，您可以看到这次非常容易地就可以捕捉到数据。有关如何关闭这些竖直线的详细信息，请参阅位于以下网址的知识库文章：support.microsoft.com/kb/283110。
图 1 干扰桶显示出来时的性能数据（没有逗号分隔符）（单击该图像可查看大图）
图 2 较为清晰的数据视图（带有逗号分隔符）（单击此图像可查看大图）
第二个技巧是在数字中添加逗号分隔符，以便能够更轻松地读取计数器中显示的值。Windows Vista 和 Windows Server 2008 默认启用逗号分隔符。但是，在先前版本的 Windows 中，“性能监视器”默认情况下是不启用逗号分隔符的。
这听起来可能感觉差别并不太大，但请看一看图 1，它显示的是没有逗号分隔符的性能计数器，然后再看一看图 2，它显示的是使用逗号分隔符的计数器。我觉得后者的可读性要强得多。有关在 Windows XP 中向性能计数器添加逗号分隔符的一些简单说明，请查看位于以下网址的知识库文章：support.microsoft.com/kb/300884。

测量对象和测量时间
当资源达到其容量限制时就会出现瓶颈，导致整个系统的性能减慢。产生瓶颈的原因通常是资源不足或配置错误、组件出现故障以及程序提出了错误的资源请求。
有五个主要资源领域可能会导致瓶颈现象并影响服务器的性能：物理磁盘、内存、进程、CPU 和网络。如果过量使用以上任意资源，服务器或应用程序的速度就可能会明显减慢甚至可能崩溃。我将逐一介绍这五个领域，提供有关计数器使用原则的指导以及提供测量服务器状态时采用的建议阈值。
由于采样间隔对日志文件的大小和服务器负载都具有非常重要的影响，因此应根据问题发生的平均消耗时间来设置采样间隔，以便能够在下次发生问题之前建立一个基准。这样您就可以找出导致问题的所有趋势。
在常规操作过程中，十五分钟是一个比较合适的建立基准的间隔。如果发生问题所消耗的时间平均约为四小时，则将采样间隔设置为 15 秒。如果发生问题的时间为八小时或更长，采样间隔时间不应少于五分钟；否则您会得到一个庞大的日志文件，致使数据分析变得异常困难。

硬盘瓶颈
由于磁盘系统存储和处理服务器上的程序和数据，因此影响磁盘使用情况和运行速度的瓶颈会极大地影响服务器的整体性能。
请注意，如果服务器尚未启用磁盘对象，则需使用命令行工具 Diskperf 来启用它们。另外还要注意，% Disk Time 可以超出 100%，因此我更倾向于使用 % Idle Time、Avg. Disk sec/Read 和 Avg. Disk sec/write 来更准确地了解磁盘的繁忙程度。在位于以下网址的知识库文章中，您可以找到更多有关 % Disk Time 的信息：support.microsoft.com/kb/310067。
以下是 Microsoft 服务支持工程师用来监视磁盘的计数器。
LogicalDisk\% Free Space 它测量选定逻辑磁盘上的可用空间百分比。请注意，如果此值低于 15%，则表示可用空间不足，操作系统无法存储关键文件。一个最直接的解决方案是增加更多的磁盘空间。
PhysicalDisk\% Idle Time 它测量磁盘在采样间隔期间的空闲时间百分比。如果此计数器低于 20%，则表示磁盘系统处于满负荷状态。可考虑将当前的磁盘系统更换为速度更快的磁盘系统。
PhysicalDisk\ Avg.Disk Sec/Read 它测量从磁盘读取数据的平均时间（以秒为单位）。如果此数字大于 25 毫秒 (ms)，则意味着从磁盘读取数据时磁盘系统发生了延迟。对于托管 SQL Server® 和 Exchange Server 的关键任务服务器，可接受的阈值要低得多，约为 10 ms。最合理的解决方案是将当前磁盘系统更换为速度更快的磁盘系统。
PhysicalDisk\ Avg.Disk Sec/Write 它测量将数据写入磁盘所需的平均时间（以秒为单位）。如果此数字大于 25 ms，则意味着写入磁盘时磁盘系统发生了延迟。对于托管 SQL Server 和 Exchange Server 的关键任务服务器，可接受的阈值要低得多，约为 10 ms。可能的解决方案是将当前磁盘系统更换为速度更快的磁盘系统。
PhysicalDisk\ Avg.Disk Queue Length 它表示目前正在等待硬盘变为可用的 I/O 操作数。如果此值大于心轴数加 2，则表示磁盘本身可能也是瓶颈。
Memory\Cache Bytes 它表示用于文件系统缓存的内存数量。如果此值大于 200MB，则可能存在磁盘瓶颈。

内存瓶颈
内存不足通常是由于 RAM 不足、内存泄漏或内存开关被放置在 boot.ini 中而导致的。在讨论内存计数器之前，我先介绍一下 /3GB 开关。
内存越多，磁盘 I/O 活动就越少，而应用程序的性能也会因此得以改善。在 Windows NT® 中引入了 /3GB 开关，用于为用户模式程序提供更多的内存。
Windows 使用 4GB 的虚拟地址空间（与系统拥有的物理 RAM 大小无关）。默认情况下，下面的 2GB 是为用户模式程序保留的，而上面的 2GB 是为内核模式程序保留的。通过使用 /3GB 开关，可将 3GB 用于用户模式进程。当然，这样做的代价是内核内存仅剩 1GB 的虚拟地址空间。这可能会产生一些问题，因为 Pool Non-Paged Bytes、Pool Paged Bytes、Free System Page Tables Entries 和桌面堆都争用这 1GB 的空间。因此，必须在环境中进行全面测试后才能使用 /3GB 开关。
如果怀疑自己遇到了与内存相关的瓶颈，可以考虑一下这一点。如果 /3GB 开关并非导致问题的症结，则可以使用以下计数器来诊断可能的内存瓶颈。
Memory\% Committed Bytes in Use 它测量 Committed Bytes 与 Commit Limit 的比值，换句话说，它测量的是使用中的虚拟内存数量。如果此数值大于 80%，则表示内存不足。对此最直接的解决方案是增加更多的内存。
Memory\% Available Mbytes 它测量可用于运行进程的物理内存量（单位为兆字节）。如果此值低于总物理 RAM 的 5%，则意味着内存不足，分页活动可能会增加。要解决此问题，应增加更多的内存。
Memory\Free System Page Table Entries 它表示系统当前并未使用的页表项数量。如果此数字小于 5,000，则很可能存在内存泄漏。
Memory\Pool Non-Paged Bytes 它测量非分页缓冲池的大小（单位为字节）。在这一系统内存区域中存储的是无法写入磁盘但只要已分配就必须保留在物理内存中的对象。如果此值大于 175MB（使用 /3GB 开关时大于 100MB），则可能存在内存泄漏。一个典型的事件 ID 2019 会记录在系统事件日志中。
Memory\Pool Paged Bytes 它测量分页缓冲池的大小（单位为字节）。在这一系统内存区域中存储的是在未使用时可以被写入磁盘的对象。如果此值大于 250MB（使用 /3GB 开关时大于 170MB），则可能存在内存泄漏。一个典型的事件 ID 2020 会记录在系统事件日志中。
Memory\Pages per Second 它测量为解决硬分页错误而从磁盘读取页或将页写入磁盘的速率。如果此值大于 1,000，则可能会由于过度分页而出现内存泄漏。

﻿处理器瓶颈
处理器出现瓶颈可能是由于处理器本身没有足够的能力，或由于应用程序效率低下导致处理器能力不足。必须仔细检查处理器是否由于物理内存不足而不得不花费大量时间来执行分页。在调查可能的处理器瓶颈时，Microsoft 服务支持工程师使用以下计数器。
Processor\% Processor Time 它测量处理器用于执行非空闲线程的已用时间百分比。如果此值大于 85%，则表明处理器性能不足，可能需要为服务器配备速度更快的处理器。
Processor\% User Time 它测量处理器在用户模式下花费的已用时间百分比。如果此值较高，则表示服务器正忙于处理应用程序。一个可能的解决方案是优化会耗尽处理器资源的应用程序。
Processor\% Interrupt Time 它测量在特定的采样间隔期间处理器用于接收和处理硬件中断的时间。如果此计数器的值大于 15%，则表示可能存在硬件问题。
System\Processor Queue Length 它表示处理器队列中的线程数。如果此值经常比 CPU 数量的两倍还多，则表示服务器的处理器能力不足。

网络瓶颈
网络瓶颈顾名思义会影响服务器通过网络发送和接收数据的能力。原因可能是服务器的网卡存在问题，或者网络处于满负荷状态，需要对其进行分段。可使用以下计数器来诊断可能的网络瓶颈。
Network Interface\Bytes Total/Sec 它测量通过每个网络适配器发送和接收字节（包括分帧字符）的速率。如果发现使用的接口超过 70%，则表示网络处于满负荷状态。对于一个 100-Mbps 的 NIC 而言，使用的接口是 8.7MB/sec (100Mbps = 100000kbps = 12.5MB/sec* 70%)。出现这种情况时，可能需要添加一个速度更快的网卡或对网络进行分段。
Network Interface\Output Queue Length 它测量输出数据包队列的长度（以数据包为单位）。如果此值大于 2，则表示网络处于满负荷状态。可通过添加一个速度更快的网卡或对网络进行分段来解决此问题。

进程瓶颈
如果进程异常或未经优化，服务器性能将会受到严重影响。线程和句柄泄漏最终会使服务器速度减慢，过度使用处理器会使服务器变为爬行速度。在诊断与进程相关的瓶颈时，需要使用以下计数器。
Process\Handle Count 它测量某个进程当前打开的句柄总数。如果此计数器的值大于 10,000，则表示可能存在句柄泄漏。
Process\Thread Count 它测量某个进程中目前处于活动状态的线程数。如果在最小线程数和最大线程数之间此数值超过 500，则可能存在线程泄漏。
Process\Private Bytes 它表示此进程已分配的且无法与其他进程共享的内存数量。如果在最小线程数和最大线程数之间此数值大于 250，则可能存在内存泄漏。

结束语
现在，您已经了解了 Microsoft 服务支持工程师都使用哪些计数器来诊断各种瓶颈问题。当然，您很可能会定制一组自己喜欢的计数器来满足您的特定需求。在每次需要监视服务器时，您可能会希望能够不必每次都手动添加所需的计数器以节省时间。幸运的是，可通过“性能监视器”中的一个选项将所有计数器都保存在一个模板中供以后使用。
您可能还没搞清楚是应该在本地还是在远程来运行“性能监视器”。以及在本地运行“性能监视器”时究竟对性能有何影响。其实它们均取决于具体的环境。如果将间隔设为至少五分钟，则对服务器的性能影响几乎可以忽略不计。
如果知道服务器存在性能问题，则您可能希望在本地运行“性能监视器”，因为当服务器的资源即将耗尽时，“性能监视器”可能无法从远程机器捕获数据。实际上从中心计算机远程运行非常适合希望监视多台服务器或将其作为基准的情形。

Steven Choy 是 Microsoft 主现场工程部的一名高级主现场工程师。他为政府机构和商业客户提供桌面部署和迁移、补丁管理以及组策略方面的项目支持。他目前的主要研究方向是服务器虚拟化和服务器运行状况。


System Center
System Center Operations Manager 中的 Windows PowerShell
Marco Shaw
概览：
  • OpsMgr 命令外壳
  • OpsMgr Monitoring 提供程序
  • 自动化常见的管理任务
  • 一些实际的 Windows PowerShell 示例

内容
Operations Manager 命令外壳
OpsMgr Monitoring 提供程序
自动化常见任务
实际示例
结束语
Windows PowerShell 是一种用于自动执行任务的功能强大的新型脚本编写语言，System Center Operations Manager 2007 (OpsMgr) 赋予了管理员对这种语言的访问权限。自从 2006 年 11 月向公众发布以来，其下载次数已超过两百万。
在本文中，我将介绍 Windows PowerShell® 并讨论如何将其应用到 Operations Manager 中。我将展示一些可通过 Windows PowerShell 以更简单、更自动化的方式来完成的常见任务，还会向您推荐一些网站，其中提供了许多有用的脚本和解释。另外我还收集了许多 Windows PowerShell 专家的独到见解和博客帖子。
虽然 Microsoft 已开始发布 Windows PowerShell 2.0 的社区技术预览版 (CTP)，但这些版本还无法马上应用到生产中，它们尚未在 OpsMgr 中进行测试，因此不能安装到生产系统中。

Operations Manager 命令外壳
在 OpsMgr 中通过命令外壳来访问 Windows PowerShell，命令外壳类似于默认的 Windows PowerShell 环境，不同之处在于它加载了一个控制台文件和一个脚本，可通过 OpsMgr cmdlet、函数以及默认连接来初始化环境。
命令外壳可以通过 OpsMgr 的 Start（开始）菜单上的图标来启动，也可以通过右键单击 OpsMgr UI 控制台中的计算机名称（请参阅图 1）来启动。这会将您直接带入 OpsMgr Monitoring 驱动器路径中（稍后会对其进行介绍）。
图 1 通过 OpsMgr UI 打开命令外壳（单击图像可查看大图）
Windows PowerShell 通过 OpsMgr SDK 与 OpsMgr 相连接。让管理员感到幸运的是，对于希望通过命令行来自动执行或完成的许多任务，系统都已为其提供了 cmdlet。如果没有用于某个特定任务的 cmdlet，可使用 Windows PowerShell 与 SDK 进行交互。
Operations Manager 命令外壳提供的命令都包括在一个管理单元中，管理单元是一个 DLL，它由 Windows PowerShell 所加载，其中包含用于 OpsMgr 管理的 cmdlet。管理单元还包括 OperationsManagerMonitoring Windows PowerShell 提供程序。此工具也称为监控提供程序，利用它可以在连接、组和监控对象之间导航，这非常类似于文件系统的导航。
可使用 Get-OperationsManagerCommand cmdlet 获取特定于 OpsMgr 的所有 cmdlet 的列表，如图 2 所示。（在第一个版本中，它是一个并不支持 tab 键完成功能的函数；在 SP1 中则变成了 cmdlet。）初始版本的 Operations Manager 中包括 74 个 cmdlet，而 OpsMgr SP1 包括 87 个。
图 2 获取 OpsMgr cmdlet 的列表（单击图像可查看大图）

OpsMgr Monitoring 提供程序
通过使用 cmdlet Set-Location（或别名 cd），您可以浏览组和计算机的布局。默认 Monitoring 驱动器的基本布局类似于下面所示：
Monitoring:\->RMS->Groups (as defined in OpsMgr)
  ->Computers(as defined in OpsMgr)
在此处您还可以获取更多的专用对象。请注意，在本例中我仅处理一个简单的环境，其中只有一台管理服务器。管理组中安装的第一台管理服务器称为根管理服务器 (RMS)。
命令外壳启动后，将创建一个名为 Monitoring 的驱动器，将此驱动器映射到 OperationsManagerMonitoring 提供程序的根目录，并将当前位置或路径设为 Monitoring 驱动器的根目录。命令外壳随后将在注册表中搜索要连接的默认 RMS 的名称。如果 RMS 连接成功，则当前位置或路径将被设置为该连接（或 RMS）的名称，如图 3 所示。
图 3 命令外壳位置被设置为 RMS（单击图像可查看大图）

自动化常见任务
让我们来看一看 Windows PowerShell 如何处理一些最常见的管理任务。
控制维护模式 无论处理何种任务，通常都会指定希望它发生的日期和时间。我将简单介绍一下 Get-Date cmdlet，向您展示实现此功能是多么简单。图 4 显示了一些示例。
图 4 使用 Get-Date cmdlet（单击图像可查看大图）
正如您所看到的，我创建了一个 $date 变量，它包含了一个代表当前时间的对象。然后，我将利用一些记载的此对象支持的方法来演示如何轻松获取五分钟以及五小时以后的日期和时间。要想获取过去的值，只需用 (-5) 代替 (5) 即可。
当需要阻止来自计算机的所有警报时，即可启用维护模式。OpsMgr 2007 允许您将某个 Windows® 服务（或是特定的数据库）而不是整个计算机或组置于维护模式中。以下三个 cmdlet 专门用于处理维护模式任务：Get-MaintenanceWindow、New-MaintenanceWindow 和 Set-MaintenanceWindow。
要在命令外壳内部将计算机置于维护模式中，可使用 Monitoring 提供程序导航到所需的计算机或监控对象，然后调用 New-MaintenanceWindow cmdlet，如图 5 所示。正如您看到的，此操作将把名为 Denver.contoso.com 的计算机置于维护模式中。我还定义了维护窗口立即生效的开始时间以及一小时后生效的结束时间。请注意，使用此方法将计算机置于维护模式并不会停止所有警报，因为此对象的 HealthService 和 HealthServiceWatcher 实例仍处于启用状态。
图 5 使用 New-MaintenanceWindow cmdlet（单击图像可查看大图）
Microsoft OpsMgr 团队的项目经理 Boris Yanushpolsky 提供了一些非常方便的 Windows PowerShell 代码，可用来将引用某台计算机的所有对象设为维护模式，并且他还解释了在创建脚本后应如何使用此代码。要了解更多信息，请访问他的博客：blogs.msdn.com/boris_yanushpolsky/archive/2007/07/25/putting-a-computer-into-maintenance-mode.aspx。
有时需要确定维护模式中是否包括不应存在的对象。但是，要通过遍历所有对象的方式进行寻找，工作量可能会相当大。幸运的是，Boris Yanushpolsky 再次带着 Windows PowerShell 脚本前来解困，这次的这个脚本使用的是 OpsMgr SDK。您可以直接从他的博客帖子 (blogs.msdn.com/boris_yanushpolsky/archive/2007/08/06/so-what-is-in-maintenance-mode.aspx) 下载脚本代码并粘贴到命令外壳窗口中，以获取处于维护模式的所有对象的列表。
当某个对象处于维护模式时，您可能希望在最初指定的结束时间之前结束维护期。如果熟悉 Windows PowerShell，您可能希望能有一个包含 stop 或 remove 动词的 cmdlet，但实际上必须要使用 Set-MaintenanceWindow，如图 6 所示。
图 6 使用 Set-MaintenanceWindow 更改结束时间（单击图像可查看大图）
管理代理 管理员经常需要处理代理，共有六个 cmdlet 和一个函数（截至当前版本）用来处理各种与代理相关的任务。可通过以下命令获取它们的列表：
Get-Command *-agent*
从 SP1 版本开始，Install-AgentByName 被打包为一个 cmdlet 而非函数。建议使用 Install-AgentByName cmdlet，因为它所提供的支持和一致性基础更为出色。
在命令外壳随附的内置帮助中提供了一些有关 Install-Agent 和 Uninstall-Agent cmdlet 使用方法的不错示例。Microsoft OpsMgr 团队的高级软件设计工程师 Roger Sprague 在他的博客中提供了一种替代方法，图 7 再现了该方法（原帖地址：blogs.msdn.com/scshell/archive/2006/09/28/getting-started.aspx）。
此脚本非常适合 OpsMgr RTM（必须位于监控提供程序的根目录 — 在本文中为 monitoring:\oxford.contoso.com），但它不能用于 OpsMgr SP1。为使其能在 OpsMgr SP1 中正常运行，应将图 7 中的第一条命令改为：
$managementServer = Get-RootManagementServer
图 7 安装代理
# Get the Root Management Server.
$managementServer = Get-ManagementServer -Root: $true

# Create the discovery configuration for computer2 and computer3.
$discoConfig = New-WindowsDiscoveryConfiguration -ComputerName: computer2, computer3

# Discover the computers.
$discoResult = Start-Discovery -ManagementServer: $managementServer -WindowsDiscoveryConfiguration: $discoConfig

# Install an agent on each computer.
Install-Agent -ManagementServer: $managementServer -AgentManagedComputer: $discoResult.CustomMonitoringObjects
此时，代理被安装在要监控的远程系统中，但还有最后一步，即管理服务器必须实际接受这个新代理，系统才会完全受到监控。如果不采取进一步的行动，监控服务器会自动接受这个新代理以便进行监控。但是，也可以使用 Get-AgentPendingAction cmdlet 来快速跟踪此接受过程。下面的单行命令可以快速跟踪代理接受过程：
Get-AgentPendingAction | Where Object {$_.AgentName –like
'computer*'} | Approve-AgentPendingAction
通过将其传送到 Reject-AgentPendingAction 而非 Approve-AgentPendingAction，可阻止 OpsMgr 服务器接受此代理（如果操作仍处于未完成状态）。如果它不是未完成的，则改用 Uninstall-Agent cmdlet。
正如我提到的，也可以使用 Install-AgentByName 在命令行中直接指定将要安装代理的计算机。
使用管理包 有四个 cmdlet 可帮助您处理各种管理包任务。可使用以下命令列出它们：
Get-Command –noun ManagementPack
下面的简单命令可列出目前安装的管理包及其版本号：
Get-ManagementPack | Format-Table –autosize
现在，我将使用命令外壳来安装两个常用管理包（使用以下安装程序）：
  • Internet Information Services System Center Operations Manager2007 Management Pack.msi
  • Windows Server® Base OS System Center Operations Manager2007 Management Pack.msi。
由于我的目标是展示命令外壳如何使常规任务更容易，因此我将尽可能使用最少的命令来实现此目的（如图 8 所示）。我本来可以更改此安装过程以将 quiet 标记传递到安装程序（.msi 文件），但我想手动选择要将文件提取到的位置。
图 8 安装管理包（单击图像可查看大图）
接下来，我需要安装常用库文件，方法如下：
Get-ChildItem –Path C:\MPs –filter *Library.mp |
ForEach-Object
  {Install-ManagementPack –filePath $_.FullName}
然后安装另一个必需的管理包：
Get-ChildItem –Path C:\MPs –filter *200?.mp |
ForEach-Object
  {Install-ManagementPack –filePath $_.FullName}
如图 9 所示，内置的命令外壳帮助提供了一些非常出色的示例，可帮助您了解如何使用 Export-ManagementPack cmdlet 来导出未封装的管理包。如果想要导出所有管理包，请更改以下命令行
$mps=Get-ManagementPack |
Where-Object {$_.Sealed –eq $false}

$mps=Get-ManagementPack
图 9 导出管理包（单击图像可查看大图）
操控用户角色 Get-UserRole cmdlet 提供了一些用于管理用户的功能，但奇怪的是，它并未同时提供作为补充的 Set cmdlet，而且您通常不会使用它来执行编辑或更新操作（根据 Windows PowerShell SDK 文档）。如图 10 所示，首先我获取当前用户角色的列表，然后向 Read-Only Operators 组添加一个用户（请参阅图 11）。
图 10 显示用户角色（单击图像可查看大图）
图 11 添加用户（单击图像可查看大图）
启用审核收集服务 (ACS) ACS 是 Operations Manager 2007 中的一项新的可选功能，简单地说，它提供了一种集中的方式来处理安全审核信息。默认情况下 ACS 是不启用的，通常会在 OpsMgr 部署的某个后续阶段进行配置。
当需要为 ACS 启用大量代理时，Windows PowerShell 可通过帮您自动执行设置过程来为您解围。在 OpsMgr 测试版阶段，Microsoft 提供了一个脚本以在所有代理中启用 ACS。SystemCenterForum.org 的撰稿人和博客作者 Neale Browne 在这方面更深入了一步，添加了对其他参数的支持。
SystemCenterForum.org 站点（一个提供各种 Microsoft® System Center 解决方案的社区站点）提供了两个不同的 Windows PowerShell 脚本，用来自动化 ACS 的设置。要在某个特定组中设置所有代理，可使用 systemcenterforum.org/wp-content/uploads/ACSBulkEnableGroupDisplayName.zip。要设置所有受监控的代理，请下载 systemcenterforum.org/wp-content/uploads/ACSBulkEnableAllAgents.zip。
启用代理代表 OpsMgr 环境可能包括无代理的受监控设备。必须将这些设备分配到提供远程监控的管理服务器或受代理管理的设备。可通过以下网址获取有关使用 Windows PowerShell 脚本配置大量代理的详细说明：systemcenterforum.org/enable-agent-act-as-a-proxy-in-bulk-via-powershell。以下网址提供了更新版本的脚本：systemcenterforum.org/wp-content/uploads/SetAgentProxyBulk_FQDN.zip。
有时，特定管理包需要代理还要充当委托代理这一角色。如需详细信息，请参阅管理包文档。

实际示例
以下实际示例进一步演示了 Windows PowerShell 如何帮助实现自动化。
解决警报 您是否曾经不得不删除某个特定计算机的一些警报？这可能是由于应用程序出现了问题或者警报没有被主动解决。下面的单行命令将解决所有解决状态为 0 的警报：
Get-Alert –criteria 'ResolutionState = ''0''' |
Resolve-Alert | Out-Null
以下示例与第一个示例的功能完全相同，但在包含更多未解决警报的更大规模环境中，它的运行速度要快得多：
Get-Alert | Where-Object {$_.ResolutionState -eq 0} |
Resolve-Alert | Out-Null
造成性能差异的原因是在使用条件参数时，传递的值被直接提供给了 SQL Server® 数据库，并且只返回了相关的数据。这可以减少必须传回 Windows PowerShell 控制台的对象。
现在，您就有了一种可以快速删除某台计算机中所有未解决警报的方法。根据需求的不同，您也可以将它设为自动运行。
最后，可通过以下命令快速查看某一天的所有警报：
Get-Alert -criteria 'TimeRaised >= ''4/25/2008'''
可以非常方便地更改日期值，并可将输出传送到 Resolve-Alert cmdlet。
测试警报 有时，您可能希望能够监控 Windows 事件查看器中的特定事件并测试它们。以下两行命令将创建一个快速事件日志条目：
$api=New-Object -comObject MOM.ScriptAPI
$api.logscriptevent("API test",100,0,
  "Test using PowerShell")
但在默认情况下，它会写入到 Operations Manager 的事件日志中，而这可能并非是您监控要记录的特定事件的位置。幸运的是，Microsoft 的高级现场解决方案工程师 Stefan Stranger 编写了一个在 Windows 事件查看器中创建事件的脚本，可以在写入特定日志时提供更大的灵活性。您可以在 go.microsoft.com/fwlink/?LinkId=120308 找到该脚本。（Stefan 已将该脚本打包在一个 .cab 文件中。您需要下载此文件，然后右键单击它来提取此脚本。）
对于 Stefan 编写的这个脚本，唯一需要注意的是针对事件来源输入的值将决定条目被写入哪个日志。要确保警报被导向到正确的日志，最简单的方法或许是打开 Windows 事件查看器并查找最后一个条目的事件源。
设置所有者 有时，自动设置警报的所有者可能会非常有用。下面的这个简单方法可通过命令外壳来实现此目的：
$alert = Get-Alert
  -id f3f73d62-37ab-45ce-a7ff-2bdda0dfaeb4
$alert.set_owner("Administrator")
$alert.update("Updated owner")
此代码的第一行会获取特定警报对象的 ID 并将它传递给 $alert 变量。在第二行中，该变量被用于设置所有者，最后将更新应用到 OpsMgr 数据库。如果使用以下命令检查警报的所有者，则它会变为：
Get-Alert -id f3f73d62-37ab-45ce-a7ff-2bdda0dfaeb4 |
Select-Object Owner
要为整组警报设置所有者，可将代码简化为：
Get-Alert | ForEach-Object {$_.Set_
  Owner("Administrator");
  $_.Update("Owner set")}
恢复监控状态 有时您可能会遇到处于“未受监控”状态的代理。此时，您可能需要快速将所有代理恢复到完全受监控的状态，然后再尝试确定究竟发生了什么。通过直接在命令外壳中运行图 12 所示的脚本，可恢复对受影响的所有代理的完全监控。
图 12 重置运行状况服务存储
$all="Microsoft.SystemCenter.AllComputersGroup"
$agents = Get-ChildItem Microsoft.SystemCenter.AllComputersGroup | `
  Where-Object {$_.HealthState -eq 'Uninitialized'}
foreach ($agent in $agents)
{
$agent.DisplayName
Push-Location $all\$agent\Microsoft.SystemCenter.HealthService
Get-Task | Where-Object {$_.Name -eq "Microsoft.SystemCenter.ResetHealthServiceStore"} | `
    Start-Task -Asynchronous
Pop-Location
}
请看一看图 12 中的代码。声明变量后，我获取了此 RMS 中所有代理的列表并筛选出了可能存在问题的代理。然后我异步调用了一个任务，在筛选后的列表中重置所有代理的“运行状况服务存储”。
将警报与管理包相关联 图 13 显示了如何获取所有新警报的列表以及每个警报所关联的管理包。
此代码需要一些技巧来确保所有管理包名称都能够被解析。使用的 cmdlet 可能会有所不同，具体取决于警报是来自规则还是来自监控器。（请注意，在图 13 中，我需要针对 Get-Monitor cmdlet 实现一个简单的解决方法。从 OpsMgr SP1 开始，cmdlet 已支持一个新的 ID 参数，这可能会使代码略微得到简化。）
图 13 查找管理包
Get-Alert | Where-Object {($_.PrincipalName -ne $null) -and ($_.ResolutionState = '0')}| `
Format-Table –autosize PrincipalName,Severity, `
  @{Label="MP"
      Expression={If(!($_.IsMonitorAlert)){
        ForEach-Object {
          ((Get-Rule $_.MonitoringRuleId).GetManagementPack()).DisplayName}
       }
       Else{
         ForEach-Object {
          $id=$_.ProblemId
          ((Get-Monitor -criteria "Id='$id'").GetManagementPack()).DisplayName}
         }
   }
}
易于报告 在升级环境时，可能需要审核所有已安装的代理的版本。只需使用一个简单的脚本即可打印出一份不错的报告：
Get-Agent| `
Format-Table DisplayName,@{ `
  Label="Version"
  Expression={ `
    switch ($_.Version){
    "6.0.5000.0" {"RTM"}
    "6.0.6246.0" {"SP1 (RC)"}
    "6.0.6278.0" {"SP1 (RTM)"}
    }
  }
}
图 14 显示了此脚本的输出。此脚本是 systemcenterforum.org/checking-operations-manager-2007-agent-and-server-versions-via-powershell 中所提供示例的扩展版本。
图 14 显示了某些代理版本的输出（单击图像可查看大图）
计划任务 您可能希望定期运行某个 Windows PowerShell 脚本。假设使用一台客户端计算机来连接和管理 OpsMgr 服务器，并且在本地已经安装了 OpsMgr 管理工具。同时假设您希望定期（例如每天）运行代理版本报告，并将输出保存到一个以当前日期作为名称的文件中。您可以使用 Windows 内置的任务计划程序从本地计算机中运行脚本。
为此，只需建立一个新任务并将程序设为 powershell.exe（通常位于 C:\Windows\System32\WindowsPowerShell\v1.0 下）即可。创建了任务后，编辑此任务并将命令设置为如下所示运行：
C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe
  –Command "& {& 'c:\agent_report2.ps1'}"
事实证明，我必须要对原始 Windows PowerShell 代码进行相当多的更改，如图 15 所示。我必须添加 OpsMgr PowerShell 管理单元、创建映射到 OperationsManagerMonitoring 提供程序的 Monitoring 驱动器，还要创建一个到 RMS 的连接。另外我还需要加载 OpsMgr 自定义 Windows PowerShell 脚本 (Microsoft.EnterpriseManagement.OperationsManager.ClientShell.Startup.ps1) 以加载 OpsMgr 专用的函数。
图 15 计划代理版本脚本
Add-PSSnapin Microsoft.EnterpriseManagement.OperationsManager.Client
New-PSDrive Monitoring Microsoft.EnterpriseManagement.OperationsManager.Client\
  OperationsManagerMonitoring ""
New-ManagementGroupConnection Oxford.contoso.com

Set-Location 'C:\Program Files\System Center Operations Manager 2007'
./Microsoft.EnterpriseManagement.OperationsManager.ClientShell.NonInteractiveStartup.ps1

$file="C:\$(Get-Date -f `"MMddyyyy`").rpt"

Get-Agent -Path Monitoring:\Oxford.contoso.com | `
Format-Table DisplayName,@{ `
  Label="Version"
  Expression={ `
    switch ($_.Version){
    "6.0.5000.0" {"RTM"}
    "6.0.6246.0" {"SP1 (RC)"}
    "6.0.6278.0" {"SP1 (RTM)"}
    }
  }
} | Out-File $file
但事情还没结束。您可能已经注意到，每次运行此任务时，如果有人登录正在运行脚本的系统，屏幕上就会弹出一个黑色的控制台窗口。Sapien 公司的 Don Jones 和 Jeffery Hicks 提供了一个用来解决此问题的小技巧，可在 blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell 中找到它。
一般来说，需要在 VBScript 中将脚本封装起来。为此，应该使用类似于图 16 所示的代码，而不应从计划任务调用以下命令：
C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe
  –Command "& {& 'c:\agent_report2.ps1'}"
图 16 隐藏弹出窗口
Dim objShell
Set objShell=CreateObject("WScript.Shell")

'enter the PowerShell expression you need to use short filenames and paths
strExpression="'c:\agent_report2.ps1'"

strCMD="powershell -nologo  -command " & Chr(34) & _
"&{&" & strExpression &"}" & Chr(34)

'Uncomment next line for debugging
'WScript.Echo strCMD

'use 0 to hide window
objShell.Run strCMD,0
现在，该任务将使用 wscript.exe 程序，并且调用过程将类似于下面所示：
C:\WINDOWS\System32\wscript.exe C:\agent_report.vbs
最后，可以创建自动化报告，以避免登录用户看到此过程。

结束语
本文快速介绍了 OpsMgr 2007 中提供的全新自动化功能，并概要讲述了如何使用 Windows PowerShell 来实现 OpsMgr 的管理。
非常感谢本文提及的所有人员以及身为 MOM MVP 和 SystemCenterForum.org 创始人的 Pete Zerger 所提供的宝贵帮助。

Marco Shaw 是一家加拿大电信公司的 IT 系统分析师。他从事 IT 行业已有 10 多年的时间，最近还荣获了 Windows PowerShell MVP 奖。Marco 还是新的 PowerShell 社区网站（powershellcommunity.org）的社区副主管。他的博客地址是 marcoshaw.blogspot.com。


Internet 信息服务
扩展 ASP.NET 应用程序：经验教训
Richard Campbell
概览：
  • 开发人员/IT 协作的重要性
  • 了解主体扩展策略
  • 在团队内共享知识
  • 就核心知识集达成共识

目录
扩展的基础知识
交流想法
网络人员需要了解的开发知识
开发人员需要了解的网络知识
重回扩展
协同灭火
作为顾问，我曾参与的每一次 ASP.NET 应用程序成功扩展都是开发人员（构建者）与网络管理员（实际运行者）之间协作的结果。遗憾的是，这种必要的协作在应用程序
生命周期初始并不总是很明显。因此，在应用程序生命周期开始时我参与的机率很小，只有在最终出现问题的时候才有机会介入。
没有任何应用程序第一次就能得到有效扩展，所有适宜的条件并非能唾手可得，这是个简单的事实。为成功扩展某个应用程序，您需要了解该应用程序的构建方式以及其运行所处操作环境的工作原理。换句话说，您既需要来自开发人员的信息，也需要来自网络人员的信息。没有这种综合知识，成功只是个幻想。

扩展的基础知识
在深入研究之前，让我们先为实际扩展 ASP.NET 应用程序打好基础。通常有两种基本策略可以采用，即规范化和分发，大多数大型可扩展 ASP.NET 应用程序都使用这两种策略。此外，本书中可帮助您扩展 ASP.NET 应用程序的每个技巧均可划分为其中的某一个策略。
规范化需要分隔应用程序的元素，以使其可以单独扩展。例如，您可以构建专用的映像服务器，而不是使用呈现 ASP.NET 页面的相同服务器。映像服务器的最佳配置与 ASP.NET 服务器完全不同。此外，如能将您的映像请求从应用程序的其余部分分离出来，就可以使用第三方资源来提供映像其他资源文件也可采用这种方法。
而分发涉及在多个服务器（通常称为 Web 场）中均衡传播应用程序。ASP.NET 应用程序特别适合分发，因为每个页面请求相对较小，而且指定用户的交互大部分独立于其他用户。分发实际上是“向外扩展”原理的体现，即多个性能一般的服务器共同为用户提供服务，而不是“向上扩展”方法（由一个超强的服务器完成这项工作）。
将规范化和分发结合在一起会提高效率，您可以只分发应用程序中那些对性能要求高的元素。例如，如果您已经创建了专门的映像服务器，但映像服务还够，您可以添加映像服务器，而不是针对整个应用程序添加服务器。当您深入研究改进 ASP.NET 应用程序的性能和可扩展性时，将这些策略铭记在心是非常重要的。

交流想法
在每个 ASP.NET 应用程序生命周期内的某些时候，开发人员和网络/IT 人员可能要举行会议。如果幸运的话，这将在应用程序部署之前进行，但有时只有在发生了危机之后才会进行，例如，应用程序在测试环境中运行良好，但发给用户之后运行非常缓慢（这时我这样的顾问就该登场了）。
开发人员和网络人员开会主要是为交换信息。开发人员对应用程序非常了解，就像网络人员了解操作环境一样。每个小组都需要了解另一小组的数据，他们在应用程序生命周期内越早交流，效果就越好。
这种会议不应是在危机时刻才首次召开。两个团队之间如果没有深入了解，就很难找出应用程序未按要求执行的原因。而且，为了摆脱责任，认为另一方对问题负完全责任的情况是相当容易出现的。这种态度是极不公正的，因为任何极其复杂的问题总是需要双方共同来解决的。
然而，即使在万事顺利的时候，这样的会议也可能是极具挑战性的。我编排的会议通常是网络人员和开发人员分别位于桌子的两侧。他们相互对视。为展开交流，我点明会议的主旨：相互汲取知识。谁先发表意见都没关系。我首先介绍网络需要从开发中了解的内容。

网络人员需要了解的开发知识
每个 ASP.NET 应用程序都有其自己的特点，但有一些关键元素适用于所有情况。web.config 文件便是其中之一（请参见图 1）。Web.config 是开发与网络之间的交点。它有时是由开发人员配置的，有时是由网络人员配置的。不管怎样，web.config 中包含的内容对硬件和网络配置都施加了限制，且直接影响应用程序的运行方式。详细探究 web.config 文件的每个小细节都需要整本书的篇幅；此处重点强调两个组均需要研究 web.config 文件并就其所代表的配置达成一致，而且还要就各种设置对应用程序和环境的影响达成一致。
图 1 显示一些应用程序设置和自定义错误配置的基本 web.config（单击图像可查看大图）
例如，web.config 的 <authorization> 部分指定将如何在应用程序中对用户进行身份验证，因而定义了依赖关系。如果应用程序使用 Windows® 身份验证，它可能要依靠 Active Directory®。如果它使用基于窗体的身份验证，则依赖用户帐户的数据存储。这的确是很值得交流的。
<customErrors> 部分很值得注意，因为它会影响向用户显示失败信息的方式。这并不是一个复杂的设置，但讨论它可以了解将会有什么样的错误页面。在协作早期可能不会出现任何自定义错误页面，这也是值得讨论的一个议题。
web.config 的 <appSettings> 部分尤为重要。这通常是开发人员存储全局值（例如，数据库的连接字符串）的位置。它不但是依赖关系的支柱，还会在计划故障转移、迁移等项目时发挥重要的作用。但由于 <appSettings> 部分是完全自定义的，因此它可以包含任何内容，并可能需要许多说明才能了解其中的内容。此部分通常留有一些孤立对象，即实际上没有在应用程序的任何位置使用过的值。
即使您的开发人员没有使用 <appSettings>，但网络/操作人员可能希望他们这样做，因为将所有数据库连接字符串置于其中是创建简单故障转移策略的有效途径。如果一个数据库服务器出现故障，可以插入替换字符串以指向其他数据库服务器。在开发伊始抓住这个机会就可以提高应用程序的可靠性和可维护性。
最后，您应注意：从扩展角度来看，web.config 中的绝对关键值是 <sessionState> 标记，它确定应用程序的会话数据存储位置。默认情况下，会话数据的存储模式为 "InProc" 或存储在 ASP.NET 应用程序的进程空间中。如果会话数据是针对进程内而配置的，则所有负载平衡必将“非常棘手”，必须始终将指定用户返回会话数据所驻留的服务器。开发人员和网络人员就此有着广泛的讨论，因为它直接影响您的扩展方式和故障转移方式。及早对此进行研究可以减轻调试应用程序的压力。
讨论一旦涉及会话状态，一般来讲很容易就会转向应用程序的负载平衡要求。一些环境有专用的负载平衡硬件，这些硬件具备特定功能，但如果应用程序无法使用这些功能，它们就没有意义。我曾遇到过硬件负载平衡与具有进程内会话数据的 ASP.NET 应用程序搭配使用的情况。结果是偶尔会莫明其妙地丢失一些会话。它看起来像是应用程序内的一个 Bug，但其实是配置错误。
网络人员需要清楚了解开发流程为应用程序准备的负载平衡架构。这无疑是一个双向对话：有哪些负载平衡架构可供使用以及应用程序可以采用哪一个架构。如在应用程序生命周期早期进行这种交流，您可以预先计划一个独立的进程外负载平衡架构，这是一项很大的优势。
当 ASP.NET 应用程序准备部署（或者初始部署）时，开发人员将非常了解应用程序各组件的运行速度。最重要的是，他们掌握系统中存在的瓶颈和潜在危机点。如果网络/操作团队了解这些瓶颈，他们便可以提前准备应对这些问题，甚至可以将其转移。
例如，我曾使用过一个应用程序，在应用程序的停机时间内每晚都有一个加载大量数据的进程。开发人员构建了数据加载机制、对其进行了测试并了解其工作原理。他们知道这会对数据库造成很大的压力，但这是解决问题的有效方法。
但他们从未告诉过网络团队会发生这一进程，或者他们已将其设计为在凌晨 1 点运行（恰好是数据库备份运行的时间）。数据库保持联机，但它在备份期间运行得十分缓慢，因为所有发送给数据库的事务都将保留在事务日志中。
直到同时进行数据加载和备份导致数据库事务日志卷用尽了磁盘空间时，才发现有冲突。将数据加载改为在凌晨 3 点启动就完全解决了这一问题，但这时危机已发生了几天。
及早对应用程序中的此类工作负荷项目进行交流可以减少许多后期的麻烦。

开发人员需要了解的网络知识
在网络人员向开发人员介绍他们的工作范畴时，我喜欢以网络图为出发点。开发人员经常看到的是如图 2 所示的网络，实际上没有任何网络，只不过是一些 Web 服务器、浏览器和 Internet。
图 2 开发人员的简单网络构想（单击图像可查看大图）
当然，实际情况要远为复杂。图 3 所示也是个简化图，但更接近于实际。当您查看图 3 的时候，立即会产生一些疑问，例如，“虚拟专用网络 (VPN) 用户如何使用应用程序”或“内部用户与公共用户在身份验证方面有何差别”等。
图 3 开发人员需要了解的实际网络（单击图像可查看大图）
显然，仅仅提供网络图是不够的。对网络进行详细说明也是非常重要的，因为仅仅查看图表，无法准确了解哪些元素将影响应用程序。您需要介绍公共用户、VPN 用户和内部用户的实际连接过程。讲述现有的各种防火墙规则（尤其是在更复杂的 DMZ 式网络体系结构中）通常会引发应用程序的潜在问题。
很明显，在对应用程序进行部署之前（甚至在开发启动之前）展开所有这些讨论是很有好处的，并且是必要的，关键是让与会的每一个人都了解整个网络图。
网络还是故障转移和冗余模型的领地，但是如果没有一些软件支持或至少了解行为方式，这些模型很少会按计划工作。因此需详细介绍故障的各种表现形式。如果数据库中出现了群集，这将影响与访问数据库相关的代码。例如，可以在切换服务器后重试查询吗？如果存在冗余站点，如何将数据复制到此站点？如何从一个站点切换到另一个站点？
再次重申，这种交流越早越好，迟来强过不来，应用程序中涉及的所有人员都必须了解它们的工作原理。如果故障转移解决方案在需要时却不真正起作用，那真是糟糕透顶。
最后，还有另一种需要共享的重要网络资源，即生产日志。我始终建议将生产日志提供给开发团队。网络人员对此请求的通常反应是“向我索要这些生产日志，我便会将其发送给您”。我认为这是不够的，让开发人员自己拥有检索日志的能力（通常从备份站点）是更有效的方式。
生产日志在出现危机时是必不可少的。它们通常是记录实际情况的最佳真实经验数据来源，也是唯一的来源。在一些更寻常的情况中它们具有同样的价值。当开发人员例行访问生产日志时，他们可能会对其进行彻底检查以了解新功能的工作方式。它非常适合发现您的功能没有按预期执行，并在发生危机之前纠正问题。当每个人都访问日志时，您可以更快速地对问题做出反应并尽早修复它们。

重回扩展
网络与开发之间的会议是要了解扩展 ASP.NET 应用程序所涉及的所有问题。应用程序运行的实际环境直接影响应用程序运行代码的工作方式。与扩展相关的所有策略都将影响其在该环境下的行为。应用专业化策略（例如，分离出应用程序与 SSL 相关的部件）可能需要对网络环境进行更改并对服务器本身进行更改。
甚至看似以代码为中心的更改（如使用缓存）也可能会影响环境。这是因为当您向 ASP.NET 应用程序添加数据缓存时，您在增加内存使用率的同时也降低了数据库调用的次数。结果是您可能增加了所需的 ASP.NET 服务器数或者增加了服务器上的工作线程回收数，这将在网络监视端触发事件。
扩展 ASP.NET 应用程序确实会影响开发和网络人员，因此，让他们参与决策过程是非常值得的。通常，这种协作将产生团队单独工作时不会发现的初始解决方案。例如，网络人员可了解公司内可能有助于开发人员达到性能和扩展要求的现有硬件解决方案。交流应用程序和环境的细节就能促成这些机会。

协同灭火
扩展 ASP.NET 应用程序的资源

  • 开发高性能的 ASP.NET 应用程序
  • 操作方法：扩展 .NET 应用程序
  • 操作方法：调整和扩展基于 .NET Framework 的应用程序的性能
  • 建立可扩展的体系结构
  • 充分发挥 IIS 的性能
  • ASP.NET 应用程序的扩展策略
扩展中出现的危机并不一定是件坏事情，实际上，它通常会带来一些益处，因为它是由于太多用户想运行您的应用程序而引起的，这是应用程序价值的良好佐证！但前提是应用程序必须能够工作。
有时扩展危机是由另一原因引起的，如您的公司正在进行促销、您成为博客中的焦点，或者社交网站一下将大量人员引向您的网站。您突然间必须面对保持应用程序运行这一艰巨的任务。您可能已经猜到，最好不让这种情况实际出现。开发人员和网络人员在会议上如能通过协作帮助组织应对这种危机，那是最好的结局。
要管理这种危机，第一个问题就是“我们如何检测到站点正处于负荷过重的状态？”最常遇到的情形是“我们接到 CTO 的电话”。如果最早告诉您网站出问题的消息是从外面传来的，那您就有麻烦了。电话响铃之前应该能通过某个适当的检测抢先发现问题。那当然，您仍然会接到报告问题的电话，但它至少可以为您解答问题提供一些帮助。对 CTO 说“噢？真的吗？”可不会给他留下什么好印象。
接下来的问题是：谁第一个接到电话？谁对事件做出回答？通常网络人员会接到第一个警告，但这个人可能相对缺乏经验，因此需要一个明确的上报计划。接下来要通知谁呢？如何快速进行早期诊断以查明您所面临的是何种问题，这是个不小的挑战。如果它是网络中断问题，是一种情况。但如果是扩展问题，则完全是另外一回事情。对于扩展问题，建议尽早地让开发团队的人员参与进来。
参加解决问题的每个人都需要良好的信息，因此有效的访问权限是关键所在。要尽可能多地分发信息，以便进行有效的诊断，并最终确定解决方案的范围。
通常，如果唯一的答案是编写代码，那么事件将在可以编写代码之前结束。当然应当对事件做记录，以便将来帮助确立开发优先级，但编写一大堆代码并在没有仔细测试的情况下将其投入生产是非常不合理（或明智）的做法。灭火的第一条规则都是不要让火势继续蔓延。
对于扩展问题而言，有时解决方案就是等它结束。但仍需要做出一项决策。
同时，计划这些紧急情况意味着可以快速应用多种技术。让网络和开发资源共同解决扩展问题常常可在非常合适的时机解决问题，甚至可能快到给促销带来更大的成功。
总之，从网络端吸取的教训就是高扩展、性能良好的 ASP.NET 应用程序代表构建该应用程序的人员与部署和操作人员之间的成功协作。
由于这种协作是不可避免的，因此最好尽早在两个团队之间召开会议，以便共享信息。会议的目标是了解应用程序的所有元素（功能、工作原理、所依赖的内容、在负载下的行为方式以及其应付逐渐出现的问题的方式）并达成一致。
当这种协作真正起作用时，会大大提高公司的反应速度，塑造一个在未来继续取得成功的公司，它可以在出现问题时快速做出响应并能就应用程序所需的内容明确交流目标。

Richard Campbell 是 Microsoft 的一位区域总监，ASP.NET 方面的 MVP，他还是《.NET Rocks, the Internet Audio Talkshow for .NET Developers》（转到 dotnetrocks.com）的合著者。多年来他一直为各公司提供有关 ASP.NET 性能和扩展方面的咨询服务，他还是 Strangeloop Networks 的共同创始人之一。


编辑寄语 现场直播 Tech•Ed
Joshua Hoffman

每次坐下来撰写每月的“编辑寄语”时，我都觉得有些棘手。想出一个主题通常并不困难，因为随时都有很多趣事想要与大家分享。但问题在于“编辑寄语”的撰写时间要比大家读到它的时间差不多早六周（部分原因是我们需要有足够的时间来印刷杂志，但主要原因是为了使编辑人员有足够的时间来修改我的错误）。与撰写博客不同（它可以即时收到反馈），在这种情况下很难写出“新闻”来，因为等到您阅读的时候，它可能早已不再是新闻了。
我现在正在“阳光明媚”的奥兰多参加 Tech•Ed 2008，它应该是全世界现在最重要的事情了。因此，尽管当您阅读到本文时它可能已经有点过时 … 哎 … 太难了。
有多种原因使得 Tech•Ed 对我们而言是一件激动人心的盛事。其中的一点就是，它是我们在一年中能够亲眼见到这么多读者（甚至是作者）的难得机会！虽然我们整年都可以通过电子邮件、IM 和电话进行亲切的沟通，但毕竟比不上这么多人聚在一起畅所欲言，进行思想的碰撞。
Tech•Ed 也是提前了解未来一年发展情况的一个绝佳时机。在这里一些高管人员会高屋建瓴，畅谈未来发展策略，这些都极具参考价值。我们将听到有关虚拟化、下一代 Web、系统管理方面的革命性概念等众多新动向的最新信息。
另外，我还听说了下面的一条消息。Microsoft 的技术人员和特约编辑 Mark Russinovich 将介绍安全边界的重新定义。另一名特约编辑 Steve Riley 将谈一谈有关网络边界退出历史舞台的话题 — 这真是一个让人心动的极具创意的概念！而且 Mark Minasi、Romi Mahajan、Dharmesh Godha 和我还将举行一个有关 IT 消费化的小组讨论。
我还将介绍一些为《TechNet 杂志》撰稿的入门知识，在过去的几年里我一直在做这方面的介绍，而且它也的确激励了许多初出茅庐的作者。当您读到本文时，我演讲所用的幻灯片已经发布到我们的博客上了，网址为：blogs.technet.com/tnmag，欢迎查看。谁知道呢？也许明年您就会作为我们的撰稿人去参加 Tech•Ed！
哦，别忘了还有 Tech•Ed 活动。我们也非常喜欢这些活动。
—Joshua Hoffman

衷心感谢以下 Microsoft 技术专家： Sunil Agarwal、Eric Charran、Trina Gorman、Sanjeev Nair、Isaac Roybal、Jez Sadler、Roger Sprague、Stefan Stranger、Kevin Sullivan、Jim Truher、Alan von Weltin、Michael Walsh 和 Buck Woody。


读者来信 读者心声

SharePoint 内容类型
我想要了解一些有关在 Microsoft® SharePoint® 中使用内容类型的详细信息。在哪里能找到这些信息呢？
—E.A.

此类信息的一个不错的来源是 Microsoft SharePoint 产品和技术团队博客（网址为 blogs.msdn.com/sharepoint），Pav Cherny 曾撰写了一篇有关通过自定义内容类型来标准化数据管理的文章，其网址为：technet.microsoft.com/magazine/cc194408。还有一份有关管理企业元数据的白皮书可能也会对您有所帮助，其网址为：technet.microsoft.com/library/cc262729。
另一个值得研究的资源是 Andrew May 的博客：blogs.msdn.com/andrew_may。Andrew 是 Microsoft 的一名程序员，负责针对 Windows® SharePoint Services 3.0 和 Microsoft Office SharePoint Server 2007 中的企业内容管理功能编写开发人员文档。他在博客中记载了内容类型的知识，提供了一些有关处理内容类型的技术插图海报，并解释了 SharePoint 环境中比较复杂的企业内容管理情况。

进一步加强安全性
我非常喜欢“精彩辩论：通过隐匿性来实现安全”这篇文章（2008 年 6 月，technet.microsoft.com/magazine/cc510319）。但是，由于整篇文章仅关注管理员名称的更改，我又觉得有点失望。在关于管理员名称的辩论中，我选择站在 Roger Grimes 和 Aaron Margosis 这一边，因为我确实同意它比完全不采取任何措施要好一些，并且它产生令人头痛的管理问题的可能性要低一些。但是文章中也存在一些问题 — 管理员共享虽有所提及，但整个小组并未进行深入的探讨，如果它受到阻止，毫无疑问管理员会遇到一些严重的令人头痛的管理问题。
我还喜欢这个小组讨论的尝试“降低攻击面”的利与弊。降低攻击面与通过隐匿性来实现安全基本类似，因为人们发出的大多数内容都会关闭任何能够广播位置或身份信息的项目。例如，我有许多客户都是以通过隐匿性来实现安全的名义发出 IPv6 信息的。删除服务的方式通常就像中世纪的医生一样 — 让你闭上眼睛，开始动手，然后祈祷病人不要丧命。
—Shelly B.

您认为我们对管理员名称更改这一问题重视不足，这一点我们完全同意。最初的草稿包括了许多其他示例，但如果不做删减的话，这篇文章可能会长达 20 页！因此，我们选择了一个重点关注的示例，而管理员帐户问题似乎是被提到频率最高的。不过不用担心 — 我们已督促作者在不久的将来再撰写更多有关这一主题的文章。

不够隐匿
“精彩辩论：通过隐匿性来实现安全”是一篇不错的文章。谈到它时，我意识到了两件事。首先，我相信只要隐匿性的投资回报 (ROI) 足够高，那么隐匿性就是件好事。其次，我发现大多数 IT 安全性始终都具有一个隐匿性因素。
以密码为例。随着时间的推移，我们使它们变得越来越隐匿。在早期阶段，大多数 PC 都并非必须拥有密码。之后，当计算机刚开始逐渐互连时，使用一个简单的密码已足够。随着连接性的增强，密码必须至少拥有八个字符。当这也不够安全时，我们不得不使用混合字符，然后是密码短语等等。我怀疑我们会发现旧的隐匿保护会继续变得不够隐匿。
—Tom B.

Tom，谢谢您做的这番非常深刻的评论。我非常迫切地想看到这一趋势的发展变化结果，尤其是当多因素身份验证（例如智能卡加上密码）等安全性概念变得越来越常见时。

《TechNet 杂志》海报
我想为公司的开发人员寻找几期《TechNet 杂志》中包括的 Microsoft 海报。能告诉我如何购买它们吗？
—Helen G.

这三张海报分别是：Microsoft Exchange Server 2007 组件体系结构、Windows Server® 2008 Active Directory® 功能组件以及 Windows Server 2008 功能组件。要想购买它们，在美国和加拿大请拨打 800-444-4881，在其他国家/地区请拨打 785-838-7500。


工具箱 面向 IT 专业人员的新产品
Greg Steen

监视服务器
PA Server Monitor Pro
poweradmin.com/servermonitor
您需要监视基础结构的所有部分。在最终用户发现之前就意识到发生了错误对于灾难控制和沟通而言极为重要。（此外，老板前来兴师问罪可不是闹着玩的。） 有一款工具可帮助您对服务器基础架构进行监视，它就是 Power Admin LLC 提供的 PA Server Monitor Professional Edition。
启动和运行 PA Server Monitor 非常简单，尤其是使用应用程序内置的 Smart Configuration Process 时，它可以找出 LAN 中的所有计算机并自动为每台计算机配置一组监视程序。如果您对寻找计算机的具体过程不感兴趣，也可以导入要监视的计算机的列表并为其配置监视检查。将某台计算机配置完毕后，可通过 GUI 导出该配置，以将其用作其他计算机的模板或作为备份供将来重新安装时使用。
PA Server Monitor 共提供 18 种不同的监视程序，可将它们分配给每台服务器。这些监视程序包括各种标准检查，如监视磁盘空间、事件日志错误、远程脚本执行、文件和目录变化、CPU 和内存使用率、Internet 控制消息协议 (ping) 响应以及 Windows® 服务状态等。
还有其他一些特别实用的监视程序，例如 TCP 端口监视，它可以检查基本的端口状态，还可以发送命令文本并根据预定值检查其响应。日志文件监视可检查日志文件中的文本，看其是否可以定义为正则表达式或简单文本。目录配额监视程序可帮助您确保最终用户不会超出其限制，如果超出限制，它会通过电子邮件通知用户。对于想要运行的所有自定义任务，您都可以监视其脚本执行情况。最后，您可以使用文件时效监视功能来监视邮件队列并确保它没有溢出。
为服务器定义了监视程序后，您需要定义在达到监视阈值后应执行的操作。PA Server Monitor 提供了 15 种内置操作，包括电子邮件、事件日志、消息框、日志文件、重启服务、简单网络分页协议 (SNPP) 以及定制自定义操作的脚本等。在定义操作的同时，您还可以定义操作升级链，如果监视程序在经过指定时间后仍处于错误状态，则它将开始执行附加操作。例如，您可以设置一个操作来自动重启您的网站。如果再过五分钟后检查仍失败，系统将向您的手持设备发送一封电子邮件告知您站点的状态。
随着时间的推移，您可能希望查看有关已配置的监视程序的统计信息。PA Server Monitor 具有内置报告功能，可帮助您将相关信息提供给需要该信息的人员。内置报告包括服务器摘要（显示统计信息和特定服务器的状态）、综合摘要（提供有关每台受监视计算机的一句话综述）以及图形化状态图（显示分散于各个位置的设置状态指示器）。为了能够通过 Web 浏览器进行访问，生成的报告采用了 HTML 格式，这可以在操作中心提供一种不错的体验。此外，您还可以生成具有简单图形和图表的临时报告，或导出到 CSV 文件以备今后使用。您也可以事先安排好报告时间，从而让应用程序自动定期将服务器的最新统计信息通过电子邮件直接发送给您。
PA Server Monitor 不用代理。这样做的一个好处是，只要应用程序的服务上下文以足够的权限连接到网络中的计算机，并通过 Windows 管理规范 (WMI) 及远程过程调用 (RPC) 等其他远程管理服务加以运行，您即可启动和快速运行此程序。但它的其中一个缺点是必须提升帐户级别才能连接到远程计算机。当然，也有不需要提升权限的其他服务器协议监视程序，包括 HTTP 和 SMTP。
另一个潜在的缺点是跨越复杂且分散的基础结构和网络拓扑连接其他计算机时可能会比较困难，这将取决于域和网络信任。因此，这一无代理方法最终是否适用于您的环境取决于基础结构的布局以及您打算通过服务器监视解决方案实现的功能。
价格：监视 1 个服务器 99 美元（直销价），监视 5 个服务器 349 美元（直销价）。
使用 PA Server Monitor Professional Edition 监视服务器（单击图像可查看大图）

清理重复文件
CodeGuru
hardcoded.net/dupeguru
如果您与多个最终用户一起工作或管理共享的用户磁盘空间，肯定会注意到随着时间的推移用户空间会变得越来越凌乱。原因通常是由于一个用户在多个位置保存了相同的文件，或者多个用户在多个位置保存了相同的文件。为了合并和清理该用户空间，重复查找器可能是必不可少的一种工具。一个不错的解决方案是 Hardcoded Software 推出的 dupeGuru。
此工具扫描您的目标文件夹或驱动器，并通过查看文件名和内容来确定是否是重复文件。但是，dupeGuru 采用的方法超越了基本的字符串比较范畴，它可以使用模糊匹配算法来查找其他方法可能会漏掉的重复文件。重复文件被标记出来后，您可以选择将其发送到回收站、永久删除它们、移入另一个文件夹，或通过默认应用程序打开它们让您进行最终确认。要想随后查看结果，您可将它们导出到 XHTML 格式的文件中。
在首选项中，您可以决定扫描文件时文件名和内容筛选器的限制程度；这可能会增加找到的重复文件的数量，但同时也会增加误报匹配的可能性。dupeGuru 还可以标记文件名中含有特定词语的所有重复文件。如果想要查找用户意外创建的所有带有“副本”字样的文件以及散布在不同目录中的名为“新建文件夹”的所有空文件夹，此功能会非常有用。
此软件可用于 Windows 2000 及更高版本，还可用于 Mac OS X。如果希望查找重复的音乐和照片文件，可试一试定制版本 dupeGuru ME 和 dupeGuru PE。
价格：19.95 美元（直销价）。
使用 dupeGuru 清理重复文件（单击图像可查看大图）

监视环境
pt360 Tool Suite PRO
packettrap.com
如果可以在一个界面中查看和管理各种网络监视和管理工具，那将会非常方便。除了节省大量时间（以及桌面资源）外，集成套件还允许您在实时查看各种监视程序的同时轻松地在多个监视工具之间共享数据，从而使您可以更完整地了解基础结构的状态。
如果您觉得这主意不错，可以试一试 PacketTrap Networks 开发的 pt360 Tool Suite PRO。此应用程序为 PacketTrap Networks 工具提供了一个集成的 UI，此外还具备集中处理和改进的报告功能。您可以创建自己的工具视图并将其组织到自定义的仪表板中，以便即时访问最常用的工具和基础结构状态信息。pt360 仪表板还可以转入全屏模式。在操作中心这尤其有用，它可以允许团队中的所有成员快速浏览屏幕并查看不同网络和服务器资源的状态。此应用程序支持多个仪表板，因此您可根据自己的需求在环境中创建各种视图。
要建立仪表板，只需从下拉列表选择一些小工具，然后单击各个小工具进行配置即可。这些小工具共分为五类（Application、Networking、Devices、Availability 和 Other），它们依靠简单网络管理协议 (SNMP) 和 WMI 来监视服务器、应用程序和网络设备。Application 小工具可以与 Active Directory®、Microsoft® Exchange Server 和 SQL Server® 相关联，并且它还提供了一个浏览器工具。Networking 小工具可帮助您深入了解设备接口，并提供平均数据包丢失、最高延迟以及每个客户端的接口使用率的前 10 个视图。Device 小工具提供有关 CPU 和内存使用率、可用磁盘空间、卷列表、网络接口使用率等方面的性能指示器。它们非常适合通过可配置的 WMI 查询来监视服务器的实时性能。Availability 监视程序以图表、度量、文本或列表格式显示计算机的正常运行时间。最后的一个小工具是 Other，它有一个大的数字时钟。
除了仪表板外，pt360 工具套件还提供了一些联网工具。例如，它提供了 Cisco Configurator。您可以利用它从 Cisco 设备存档、修改、上传、下载以及比较配置文件。此外还有三个不同的 ping 工具 — 一个向您提供可分类的表视图、另一个向您显示图形化的视图、第三个使您可以通过 ping 命令快速扫描一组 IP 地址。可供您使用的其他类型的扫描工具还包括 MAC 地址扫描程序、端口扫描工具、SNMP 扫描程序以及 WMI 扫描工具。
此工具套件也可作为 syslog 服务器使用，对于任何支持 syslog 的网络设备，它都可以发送、接收、记录和显示进出该设备的 syslog 消息。显示内容还支持筛选功能，因此您可以快速找出所关注的消息，从而加快故障排除过程的速度。
此套件的作用类似于普通文件传输协议 (TFTP) 服务器，它允许您在网络中的各个设备之间快速移动文件。其他工具还具有跟踪路由、Whois 和网络唤醒等功能。当然，由于它是通过 WMI 和 SNMP 连接到主机的集中式管理解决方案，因此套件存储其连接凭据的方式至关重要。幸运的是，此套件使用了 256 位的高级加密标准 (AES) 来加密凭据存储库，您可以添加、更新和删除监视基础结构时所需的信息。
价格：单个许可证 999 美元（直销价）。
图 36 使用 pt360 Tool Suite PRO 来监视您的系统（单击图像可查看大图）

管理磁盘使用情况
Database Professional
jam-software.com/treesize/index.shtml
“究竟是什么占用了服务器的所有磁盘空间！”是不是经常存在这样的疑惑？您的监控应用程序刚刚发给您一封电子邮件，通知您磁盘空间已达到下限阈值。这时您可能会想知道应该如何着手清理计算机。以及如何才能快速找出罪魁祸首以便 "Shift-Delete"。（这是不进回收站直接删除的快捷方式。）一款可能会对您有所帮助的工具是 JAM Software 提供的 TreeSize Professional。
此应用程序可在 Windows 2000 以及更高版本的 32 位和 64 位 Windows 中运行，它可以让您深入了解究竟是哪些文件占用了驱动器中的空间。您需要做的只是选择要处理的驱动器，此应用程序就会自动扫描文件夹结构。操作完成后，您可以通过七种不同的视图访问该驱动器。第一个是 Chart 视图，它会依次提供以下三种图表供您分析：饼图、条形图和相对大小框图。以上每种图表都可以让您深入不同的文件夹，快速找出占用大量空间的文件。您也可以自定义图表的颜色和样式。
接下来是 Detail 视图，它可以为您提供文件的可分类表视图，在这个视图中，您可以选择要显示的不同列。用户最常选择的是 Microsoft Office 文件的作者、文件夹中文件的平均大小、此文件或文件夹所占父目录的百分比以及硬链接等。
Extensions 视图会在您沿着文件夹向下查找时指出究竟是哪种类型的文件占用了每个目录的大部分空间。Users 视图显示的是复合视图，表示某个用户或系统帐户的文件占用了多少空间，它在确定有问题用户时起着至关重要的作用。File Ages 视图以图形化的方式显示出在过去的一天、一个月或一年（此时间段可随意选择）修改、创建或访问过的文件百分比，以找出可归档或安全删除的旧文件。然后是 Top 100 视图，它会找出驱动器中前 100 个最大的文件。最后是 History 视图，它会显示出随着时间的推移驱动器在使用模式方面的情况。
以上每种视图均可打印、保存并复制到剪贴板以备今后使用。并且，通过使用文件搜索功能快速找出最大的文件、最早的文件、临时文件、Internet 缓存文件以及重复文件，TreeSize 可以借助工具栏加快常见清理维护任务的执行速度。TreeSize Professional 还可以通过 UNC 共享来扫描网络，但由于这会涉及网络开销因而可能会对性能产生负面影响。
此应用程序还支持命令行模式。这非常适合于计划执行和整夜运行。您还可以创建 Scheduled Task 扫描，将其配置为扫描某个路径并定期生成一组有关标准计划任务的报告。这对于每晚都要监视共享用户空间和时刻关注磁盘空间使用情况的场合非常有用。
如果您想弄清楚多达 TB 的用户空间是如何被蚕食掉的，也许 TreeSize 可以帮助您了解磁盘空间使用情况并让您着手对其实行更加有效的管理。
价格：单个许可证 49.95 美元（直销价）。
通过 TreeSize Professional 管理磁盘使用情况（单击图像可查看大图）

Greg Steen 是一位技术专家和企业家，酷爱钻研技术。他总是在寻找各种新工具，以帮助 IT 专业人员更轻松地进行操作、完成 QA（质量保证）工作和开发。


SQL 问题与解答 分区、一致性检查以及其他更多内容
Paul S. Randal

问：我无意中将某个产品数据库连接到了 SQL Server® 2005 服务器，现在我打算把它连接到运行 SQL Server 2000 的正确服务器上。我尝试过分离数据库然后将其连接到 SQL Server 2000 服务器，我也尝试过通过备份和还原来执行同样的操作，但这两种方法都不起作用。为什么它无法在 SQL Server 2000 服务器上运行呢？这是我唯一的一份数据库副本。
答：首先要强调的是进行备份的重要性。DBA 通常认为备份是为了能够从损坏中或其他一些破坏性灾难中进行恢复。可您却遇上了一个不太明显的灾难 — 在升级过程中出现了问题，尽管在这种情况下它属于意外升级。但是，问题的重点在于您应当始终备份最新的完整数据库，以防数据库出现问题。
升级（无论是有意的还是无意的）是一种单向操作，因而很难逆转其效果。在两个版本的 SQL Server 之间升级时，会针对数据库执行一系列的升级步骤。每个步骤通常都包括对数据库所做的一些物理更改，并且每个步骤都会增加数据库的版本号。
例如，在将数据库从 SQL Server 2000 升级到 SQL Server 2005 时执行的其中一个主要更改就是改变数据库系统目录（通常称为系统表或数据库元数据）的结构，其中存储着有关表、索引、列、分配以及与数据库的关系和物理结构相关的其他详细信息的各种元数据。
每次执行升级步骤时，数据库版本号都会增加。例如，SQL Server 7.0 数据库的版本号为 515，SQL Server 2000 数据库的版本号为 539，而 SQL Server 2005 数据库的版本号为 611（如果启用了 vardecimal 功能，则为 612）。这将使 SQL Server 能够了解对数据库执行的最后一个升级步骤。
SQL Server 的版本无法读取已升级到更高版本的 SQL Server 数据库（例如，SQL Server 2000 无法读取已升级到 SQL Server 2005 的数据库）。这是因为较低版本没有解释升级后的结构和数据库布局所需的代码。而这也正是您升级到 SQL Server 2005 后的数据库所面临的问题：无法重新连接到 SQL Server 2000。
在缺少完整数据库备份的情况下，您的唯一选择是从已升级的数据库中导出所有数据，然后将其手动传回新的 SQL Server 2000 数据库。只要尚未使用 SQL Server 2005 中的任何新功能，您即可编写数据库结构的脚本、在 SQL Server 2000 上创建数据库，然后导出/导入数据。
要在 SQL Server 2005 中编写数据库脚本，可使用 SQL Server Management Studio 中的“对象资源管理器”（右键单击数据库并选择“任务”，然后选择“生成脚本”选项）。此向导带有自解释功能，可以生成一个脚本来创建所有对象、索引、约束、触发器等。
问：我们最近重新设计了架构以便在主表上使用表分区 — 因为我们听说这有助于提高性能。数据库存储在单个的 120GB 驱动器上，并且表包含在单个文件组中。没有需要实现的滑动窗口，只是每周会添加新分区，并且所有数据都需要在线访问。大部分查询处理的都是近一周内的数据，也有一些处理去年的数据。这似乎在单个文件组中更容易实现。我的说法是否正确，有什么需要补充吗？
答：尽管使用单个文件组似乎会比较容易，但这样使用分区可能不会给您带来任何好处。分区的主要用途是在发生灾难时提供更加有效的数据库维护手段并提高数据可用性，另外还可以创建一个可以使性能得到改善的架构。
分区的典型示例是一个具有 12 个分区的销售表，每个分区都代表去年一个月的销售数据。在月末时，系统将切换出最旧的分区（进行归档或删除），然后切换进一个新分区。这就是您所说的滑动窗口方案。当月的分区设为读取/写入，而较旧的月份设为只读。每个分区都存储在单独的文件组中。此架构可实现分区的所有好处，但它并不是适用所有情形的最优架构。
我的妻子 Kimberly 针对上述架构想出了一个主意，可以更有效地编制索引。假如将此销售表拆分成两个表，分别存储单独的读取/写入分区和其余的 11 个只读分区，并且针对两个表使用一个分区视图。
这样，读取/写入表只拥有少量索引，而只读表拥有更多索引以支持报告查询。这会使针对读取/写入数据的数据操作语言 (DML) 操作变得更加有效，因为它们不必维护过多的非群集索引。
同样，针对读取/写入数据的查询也不必处理只读数据。在 SQL Server 2005 中，查询计划中的分区消除功能并不完善，尤其是使用复杂的谓词时；但这一点在 SQL Server 2008 中已大为改善。如需更多信息，请参阅 Kimberly 的博客帖子，网址为：sqlskills.com/blogs/kimberly/default,month,2007-10.aspx#a71c70243-3d57-4940-9af7-a802b73f2f93。
为了说明我的意思，我将介绍分区针对多个文件组启用的一些功能。
部分数据库可用性 此功能是指在灾难恢复过程中，只要主要文件组在线，数据库就会在线并可供访问。如果只有一个文件组，则在还原过程中，整个数据库都会脱机。如果将数据分布到多个文件组，则在还原过程中，只有受损的文件组是脱机的，应用程序可能仍然能够继续运行。
逐步还原 此方案类似于部分数据库可用性。当只有一个文件组时，还原单位是单个页面或整个数据库。如果有多个文件组，则可以只还原单个文件组 — 从而实现部分数据库可用性。
分区数据库维护 在使用以上介绍的任何分区方案时，可针对每个分区来执行索引碎片删除操作（即使所有分区都在一个文件组中）。但如果只有一个文件组，则无法针对每个文件组执行一致性检查，而此操作可以显著减少在进行数据库一致性检查 (DBCC) 时需要处理的数据量（以及使用的 CPU 和 I/O 资源数量）。
简而言之，尽管可以在同一文件组中拥有多个分区，但在分区和文件组之间保持 1-1 映射有许多好处。
问：我们最近被一台高端数据库服务器吓坏了 — 由于内存故障导致数据库被损坏。当应用程序中开始出现随机数据时我们才发现这一情况。我们运行了 DBCC CHECKDB 并找到了所有类型的损坏。不幸的是，这一情况也出现在备份文件中，因此我们不得不手动清除坏掉的数据。
长话短说 — 我们更换了坏掉的硬件并开启了“页面校验和”功能。我们想运行定期的一致性检查，但我们没有大型维护窗口，并且我们 2.4TB 的数据库在检查时需要很长的时间。我们该怎么办呢？
答：如何针对 VLDB（超大数据库）执行一致性检查和其他维护操作的问题正变得越来越常见。在发现 DBCC CHECKDB 的运行时间超过了其维护窗口的允许值后，许多 DBA 都放弃了检查（在某些情况下，数据库处于全天候使用状态，基本没有有效的时间来长时间停止执行 DBCC CHECKDB 时所需的 CPU 和 I/O 开销）。
除了放弃和不运行任何一致性检查（我非常反对这样做）外，有以下四种方法可供您选用。我将亲自指导客户如何使用这四种方法。
使用 DBCC CHECKDB 的 WITH PHYSICAL_ONLY 选项 常规 DBCC CHECKDB 运行大量的逻辑一致性检查，从而占用大量 CPU（并且基本上是一个受 CPU 限制的操作）。使用 WITH PHYSICAL_ONLY 选项，可将检查限制为运行非常快速的 DBCC CHECKALLOC 分配位图一致性检查，然后读取和审核数据库中每个已分配的页面，从而强制所有“页面校验和”显示在待测试页面上。这将把 DBCC CHECKDB 变成一个受 I/O 限制的操作，而且运行时间非常短（实际上，它有时甚至比完整的 DBCC CHECKDB 还要快很多，因此可极大地节省时间）。
拆分一致性检查工作量 这需要将数据库中的表分成大小相同的组（最简单的方法是按页面数量拆分），然后每天晚上使用 DBCC CHECKTABLE 命令针对每个组中的所有表执行一致性检查。例如，假设有七个组，我们进行每天一组的检查，即每周一次 DBCC CHECKALLOC 和 DBCC CHECKCATALOG，这将等效于 DBCC CHECKDB（虽然完成周期延长到了一周时间）。
通过多个文件组来使用表分区 VLDB 中的最大表可被拆分成多个文件组。可能采取的一致性检查架构可以是针对存储读取/写入分区的文件组每天运行一次 DBCC CHECKFILEGROUP，此外针对存储只读分区的文件组每周运行一次 DBCC CHECKFILEGROUP。原因是只读数据已全部备份，在进行日常处理时不会用到。因此，无需经常对其执行一致性检查，因为即使此类数据发生损坏也不会造成太过严重的后果。
将一致性检查卸载到其他服务器 此选项将把常规的完整数据库备份还原到另一服务器并在该服务器上运行 DBCC CHECKDB。很显然，这种方法完全避免了在生产服务器上导致一致性检查工作量。但是其缺点就是如果发现有损坏，必须在生产服务器上运行一致性检查 — 不过发生此类事件的概率极低。
正如您所看到的，DBA 可使用多种方法来针对 VLDB 执行一致性检查，从而减少运行完整的 DBCC CHECKDB 所需的额外资源负载。至此，我已按我先前所说的为客户讲解了如何使用这四种方法。我想这些方法对您会非常有帮助。
提示：使用触发器实现服务器端逻辑
在某些情况下，您需要使用触发器来实现服务器端逻辑。但此时存在一些您必须要了解的缺陷问题。下面是一些应该牢记的重要事项。
  • 触发器是由语句触发的，而不是按行触发。也就是说，必须在触发器逻辑中添加额外的逻辑以处理多个行或没有行受到语句影响的情形（触发器是按语句触发的，即使没有行受到影响）。受影响的数据存储在数据操作语言 (DML) 语句的虚拟表中。可将这些表连接起来以便处理其中的数据。
  • 触发器在事务内部同步运行。每次想要调用外部应用程序或访问外部资源时（如果无法确定它是否会在预计的响应时间或合理的时间内返回）都要记住这一点。例如，如果对某个表触发了 Update 语句并且在该操作中有一个触发器被触发，则只有在该触发器的所有逻辑都完成后，此事务（即 Update 语句）才会完成。如果外部应用程序或进程返回一个错误代码，SQL Server 可能会取消事务并回滚该事务（具体取决于实施的错误处理和错误代码）。因此，如果需要在触发器内部执行一些外部操作而它对事务而言又不太重要（或者不必在同一范围内运行），则应将它扩展到另一个进程中并通过异步方式提取数据。SQL Server 2005 引入了 SQL Server Service Broker，它可以异步执行此类操作。
  • 由触发器内部语句导致的错误非常不容易发现。如果事务中包括多个表，则在出现错误时务必要记得检查触发器是否存在错误并执行正确的错误处理操作。如果更改数据库中的架构，务必同时跟踪触发器逻辑 — 否则，一个小小的触发器也可能会对整体性能和稳定性产生极大的影响。架构更改涉及的大部分影响都可以使用 Visual Studio® for Database Professionals 进行检查，它可以在编辑项目时执行自动化架构检查，并可以通过执行静态代码分析来检查数据类型的不一致问题。
—Jens K. Suessmeyer，Microsoft 的数据库顾问

Paul S. Randal 是 SQLskills.com 的总裁，也是 SQL Server 的 MVP。从 1999 年到 2007 年，他一直在 Microsoft 的 SQL Server 存储引擎团队工作。Paul 曾编写过 DBCC CHECKDB/repair for SQL Server 2005，并在 SQL Server 2008 的开发过程中负责核心存储引擎部分的工作。Paul 是灾难恢复、高可用性和数据库维护方面的专家，经常会出席一些会议。他的博客地址是 SQLskills.com/blogs/paul。


实用工具特别推荐 Windows Installer 清理实用工具
Lance Whitney

当您试图卸载或更新环境中某台计算机内的某个应用程序时，命令却没有执行。相反，会弹出一个错误窗口，提示该应用程序无法卸载或更新。听起来是不是很熟悉？如果是这样，您肯定想知道导致此错误的原因是什么。
使用 Microsoft® Windows® Installer (MSI) 技术安装的软件会写入特定的文件和注册表设置。如果其中的任何此类文件或设置丢失或者被破坏，就可能会导致您无法删除、更新甚至重新安装程序。此时的解决方案是删除所有 Windows Installer 信息，以便您可以全新地重新安装程序。为此，Microsoft 提供了免费的 Windows Installer 清理实用工具。
Windows Installer 清理实用工具会删除与程序的 Windows Installer 配置相关的所有文件和注册表设置。特别要注意，此工具并不删除程序的实际安装文件或注册表设置。此工具也并不会取代或接管“添加/删除程序”命令。
实际上，如果通过“添加/删除程序”或其他方法无法卸载或更新应用程序时，可改用此实用工具。删除 Windows Installer 信息后，即可重新安装应用程序。您可以随后按原样安装程序，或者更新甚至删除它。
Windows Installer 清理实用工具会显示计算机中基于 Windows Installer 的所有应用程序的列表（单击图像可查看大图）
有些人可能非常熟悉 Microsoft 命令行程序 msizap，它可以删除程序的 Windows Installer 数据。不错，此处也使用了该命令：Windows Installer 清理实用工具只是 msizap 的友好前端，这样您就不必再为讨厌的命令行选项而绞尽脑汁了。
安装此实用工具后，您会发现在 Program Files 下会嵌套一个子文件夹 Windows Installer Clean Up。在这个子文件夹中，有三个文件：msicuu.exe、msizap.exe 和 readme.txt。msicuu.exe 文件显示计算机中基于 Windows Installer 的所有应用程序的列表，您可以从中选择、取消选择和删除任意应用程序。然后，此程序会将您的选择传递给 msizap.exe 命令，由该命令删除所选应用程序的 Windows Installer 信息。
要运行 Windows Installer 清理实用工具，请转到“开始”菜单|“程序”并找到对应的文件夹，然后单击 Windows Installer Clean Up 快捷方式。您会看到计算机中基于 Windows Installer 的所有应用程序的列表（如屏幕快照所示）。选择存在问题的应用程序并单击 Remove（删除）按钮。这样该应用程序就会从 Windows Installer 数据库中被删除，而您也可以全新地重新安装它了。
您会发现在运行此清理工具后，“添加/删除程序”中将不再显示该应用程序。因此，如果最终希望删除该应用程序，首先必须重新安装它。Windows Installer 清理实用工具仅适用于使用 Windows Installer 技术安装的软件，通常也包括打包成 MSI 文件的安装。
最后还要注意，必须以管理员身份登录才能运行 Windows Installer 清理实用工具。此工具与所有 32 位和 64 位版本的 Windows 都兼容。有关此实用工具的更多信息或如果想下载此软件，请访问以下网址：support.microsoft.com/kb/290301。

Lance Whitney 是一位 IT 顾问、培训师和技术撰稿人。他花费了大量的时间来研究 Windows 工作站和服务器。15 年前，当他还是一名记者时，就开始涉足 IT 世界。


深入剖析 SharePoint 消息传递集成故障排除
Pav Cherny

代码下载位置： SharePoint2008_08.exe (416 KB)
内容
常见故障排除方法
SharePoint 消息传递体系结构
获取诊断信息
出站邮件传输
入站邮件传输
目录管理
结束语
在一个设计良好的 SharePoint 环境中，信息工作者无需改变各自的通信习惯或工作日程安排即可进行协作。他们不必不断地手动检查协作站点，SharePoint 可以将文档和其他信息（如警告和提醒）直接发送到他们的邮箱中。
而用户则可以通过回复这些邮件或将新项目以电子邮件的形式发送到文档库和列表来参与工作流。
但是，将 SharePoint® 集成到一个安全的消息传递环境需要面临诸多挑战，而且有可能会使非 SharePoint 组件对基于 SharePoint 的协作产生影响。当集成环境中出现问题时如何有效地隔离问题并消除导致这些问题的根本原因是一个难题。
在本专栏中，我将基于公认可以最快给出结果的故障排除策略来介绍 SharePoint 的消息传递集成。具体思路是首先迅速找到问题点，然后执行详细且有针对性的故障排除步骤。
在大型组织中，这一阶段式调查可能意味着在经过初始分析后需要将问题移交给其他专家，尤其是当该问题与非 SharePoint 组件相关时。但对于中小型组织而言，往往会要求 IT 管理员必须能够马上独立地排除所有相关系统的故障，这时尤其需要用到结构化的方法。
为使本专栏真正做到实用，我特意构建了一个测试环境，其中包括 Active Directory®、Exchange Server 2007 和 WSS 3.0。在随附的材料中，包括了构建此测试环境的分步说明以及本专栏中介绍的故障排除工具（可从《TechNet 杂志》 网站的“代码下载”中获取此材料）。

常见故障排除方法
也许与其他各种互操作性情况相比，对 SharePoint 消息传递集成进行故障排除更需要高度结构化的方法。有多种因素都会使此工作变得复杂异常。
很显然，您必须应对各种复杂的技术，而且当您在为邮件传输问题、邮件格式转换、安全性问题以及目录管理问题绞尽脑汁的时候，一些让人困惑不解的 SharePoint 错误消息可能也会接踵而来。在 Internet 新闻组中，到处都充斥着尚未得到解决的讨论话题和建议，很容易就会将您引入歧途 — 例如告诉您使用 SharePoint 管理中心的应用程序池标识来运行所有 Web 应用程序可以使消息传递集成能正常运行。
当然它也有许多长处。SharePoint 非常灵活。实际上，如果知道具体位置，它可以为您提供详细的故障排除信息。利用一些基本的脚本，您可以显著提高故障排除效率。
要故障排除，首先需要了解您要处理的特定问题。您需要确定问题的位置以及涉及的组件。有时可能还需要使用各种不同的系统配置来重现问题并研究 Windows® 事件日志和基于文本的日志文件。但这一点可能会比较棘手，因为有些问题只是偶发事件。当然，问题再现得越准确，您就可以越迅速地确定问题的根本原因并加以消除。另一个经常被忽略的重要目标就是记录所有配置更改和问题修复，并确保将其应用到环境中的所有相关系统（如 Web 场中的所有前端服务器）。

SharePoint 消息传递体系结构
无论何时遇到与消息传递集成有关的问题，在开始进行故障排除前，最好先喝杯咖啡或泡杯香茶，然后再着手查看 SharePoint 消息传递集成体系结构。否则可能到头来修复的是错误的问题或组件。例如，正如稍后您将看到的，当出现“拒绝访问”错误导致无法在 Active Directory 中创建联系人对象时，并不一定表示需要在 Active Directory 中修复访问权限。
在任何情况下，了解消息传递集成中每个组件的角色以及各组件彼此交互的方式都非常重要。在图 1 中，您会看到 SharePoint-Exchange 连接方案（在后续章节将对此进行详细介绍）中的一些重要组件。
图 1 SharePoint 消息传递集成体系结构（单击此图像可查看大图）

获取诊断信息
其中一个最重要的故障排除工具就是可靠的诊断信息。最为经典的是 Windows 事件日志。除此之外，您还可以使用 SharePoint 管理中心来控制 SharePoint 在向 Web 服务器写入 Windows 事件日志时采用的详细级别，方法是在 Operations（操作）页面的 Logging and Reporting（日志记录和报告）下，单击 Diagnostic Logging（诊断日志记录）。您可以指定向事件日志和跟踪日志报告的最低级别事件。如果需要较低级别的信息，跟踪日志（默认情况下位于 %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\12\Logs 下）是一个不错的选择，但它的填充速度非常快，因此使用此功能要谨慎。
另一种获取诊断信息的方法是通过配置相应的 web.config 文件来启用受影响的 Web 应用程序的调试工作，如随附材料中的 Web Application Config.pdf 所述。SharePoint 可以直接在用户界面中显示详细的跟踪信息。此方法的好处是不必分析数以兆计的跟踪数据就可以看到相关的错误信息。但缺点是必须要更改 Web 应用程序的系统配置。故障排除完毕后，请不要忘记备份原始的 web.config 文件，备份完之后再恢复原始配置。
也可以对 SMTP 服务进行配置以将详细的处理信息写入到 SMTP 协议日志中，方法是在 IIS 管理器中，选中 General（常规）选项卡上的 Enable logging（启用日志记录）复选框。确保如随附材料中的 SharePoint Messaging Integration.pdf 所述来安装 ODBC 日志记录模块和 SMTP 服务功能（即使并不打算使用 ODBC 日志记录）。否则，SMTP 服务不会写入到协议日志中。默认情况下，SMTP 协议日志位于 %SystemRoot%\System32\LogFiles\SmtpSvc1 下。它是一个文本文件，可用来详细分析 SMTP 通信并确定邮件是否已离开 SharePoint 服务器。
在与 SMTP 服务通信的集线器传输服务器上，您也可以在“发送连接器”和“接收连接器”配置中启用协议日志记录（请参阅 SharePoint Messaging Integration.pdf）。您可以使用多种其他工具（如“邮件跟踪”、“队列查看器”和“管道跟踪”等）来跟踪 Exchange Server 2007 环境中邮件在集线器传输服务器和邮箱服务器之间经过的路径。如需有关 Exchange Server 2007 邮件流问题故障排除的详细信息，请参阅主题“传输和邮件流问题”，网址为 go.microsoft.com/fwlink/?LinkID=120145。
在 Active Directory 域控制器中，您可以通过启用“目录访问”的诊断日志记录来收集详细的故障排除信息，以及通过在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics 下设置相应的注册表项来收集其他种类的信息。如果种类的值为 0x0，则意味着仅记录关键事件；而值 0x5 表示记录所有事件，包括调试信息。如果日志记录级别大于 0x3，则可能会使服务器性能降级，还可能会使 Windows 事件日志填充速度过快。在常规操作过程中，所有值都应设为 0x0。
在进行故障排除时收集有关 SharePoint、Exchange 和 Active Directory 服务器的详细诊断信息，有助于您快速而且可靠地找到问题点。TCP/IP 工具（ping、tracert 以及 telnet）和 Network Monitor 等其他一些故障排除工具也可能会派上用场，因为这些系统之间的大多数通信都是通过计算机网络来完成的。Microsoft® Network Monitor 3.1 的下载地址为 go.microsoft.com/fwlink/?LinkId=120143。

出站邮件传输
资源
  • SharePoint 产品和技术网站
  • Windows SharePoint Services 技术中心
  • Windows SharePoint Services 开发人员中心
  • Microsoft SharePoint 产品和技术团队博客
在准备好了事件日志、跟踪日志、协议日志、邮件跟踪日志和网络跟踪之后，接下来我将开始对 SharePoint 消息传递集成进行故障排除。我们首先来介绍一下简单的部分：出站邮件传输。SharePoint 支持各种配置的出站邮件传输，并且在 Web 服务器上不需要本地 SMTP 服务。但是，在完整的消息传递集成方案中，使用本地 SMTP 服务是建议的配置。图 2 显示了此方案中的一些关键组件。
图 2 出站邮件传输（单击此图像可查看大图）
此消息传递方案包括四个阶段：SharePoint 必须将邮件传输到 SMTP 服务，SMTP 服务必须处理邮件，集线器传输服务器必须接收邮件，最后 Exchange Server 2007 必须将邮件传输到最终目的地。
如果 SharePoint 无法将邮件传给 SMTP 服务，而您在用户界面中收到一个错误消息，内容可能是说电子邮件通知无法发送。其原因可能是 SMTP 服务未运行。或者 SMTP 协议日志可能会告诉您 SMTP 服务拒绝该提交尝试，错误代码为 550（未执行请求的操作：邮箱不可用），这表示问题出在 SMTP 服务上。
为验证这并非是 SharePoint 的问题，您可以使用一个基本脚本（请参阅随附材料中的 SMTP.vbs）通过 SMTP 提交一封具有相同的发件人以及收件人信息的测试邮件。如果是 SMTP 服务的问题，此脚本将不会成功。实际上，此脚本可能会为您提供有关问题根本原因的一些有价值的线索，但遗憾的是 SharePoint 并未发现，即使启用了调试功能也是如此（如图 3 所示）。
图 3 无法中继邮件（单击此图像可查看大图）
通过在 SMTP 服务配置中授予 Web 服务器中继权限然后重新启动 SMTP 服务，您即可解决 SharePoint 的邮件提交问题。现在邮件可以抵达 SMTP 服务，下一个重要的问题是 SMTP 服务能否将邮件路由到集线器传输服务器。
如果邮件仍在 Queue 文件夹中，SMTP 服务无法联系集线器传输服务器。原因可能是 Microsoft Exchange 传输服务未运行或网络通信或配置存在问题。通过使用 Telnet 客户端，您可以快速且轻松地验证能否连接到为内部通信配置的接收连接器的目标端口。
它并非必须是 TCP 端口 25。实际上，如果 SMTP 服务使用此端口，则您可将邮件传输到集线器传输服务器的默认接收连接器（它被配置为阻止匿名邮件提交）。在这种情况下，您会在 Drop 文件夹中看到一个邮件文件。（必须停止 Windows SharePoint Services 计时器服务；否则，几秒钟后邮件就会消失。）邮件文件是一个传递状态通知，它指出邮件遭拒，并提示 "Diagnostic-code:smtp;530 5.7.1 Client was not authenticated"（诊断码：smtp;530 5.7.1 客户端未通过身份验证）。
要解决此问题，应为 SharePoint 服务器创建一个专用的接收连接器。由于 SharePoint 服务器是内部系统，因此请选择 Externally Secured（外部安全）身份验证选项。这样就不必向“匿名登录”帐户授予更多权限。另外，还可以考虑使用 IPsec 来保护 SharePoint 服务器与集线器传输服务器之间的通信。
如果邮件离开 SMTP Queue 文件夹且 SharePoint 服务器和集线器传输服务器上的 SMTP 协议日志（查看 %ProgramFiles%\Microsoft\Exchange Server\TransportRoles\Logs\ProtocolLog\SmtpReceive 文件夹）指示邮件传输成功，则可以认为作业已完成（假定 Exchange Server 2007 可以将邮件路由到目的地）。正如先前提到的，如果邮件没有到达预期的 Exchange 收件人，则使用 Exchange Server 2007 中附带的邮件流故障排除工具来调查问题。请注意，如果收件人信息、垃圾邮件筛选器和邮件大小限制不正确，也有可能导致此阶段最终传递失败。

入站邮件传输
在相反的方向上，由于一些更加微妙的潜在问题使得邮件传输变得更加复杂。例如，SharePoint 产品文档建议在 DNS 中为 SharePoint 电子邮件域配置 MX 记录，此方法经常导致在 Exchange 组织中误传邮件。
Exchange Server 2007 使用发送连接器以及相关地址空间来传输邮件。它可能会将 SharePoint 邮件路由到边缘传输服务器，以便即使 SharePoint 服务器是内部系统也可以通过 Internet 进行传输。对于内部邮件传输，使用的则是发送连接器和详细的地址空间，并在连接器配置中将运行 SMTP 服务的 SharePoint 服务器指定为智能主机（请参阅随附下载中的 SharePoint Messaging Integration.pdf）。建立一个定义良好的路由拓扑以及专用的桥头服务器有助于实现从 Exchange 到 SharePoint 的可靠邮件传输。
要验证邮件是否已到达 SharePoint 服务器，应停止 Windows SharePoint Services 计时器服务。邮件将被存放在 Drop 文件夹中，因为是计时器服务来负责处理邮件并将文件附件放置在与收件人电子邮件地址相关联的文档库中（如图 4 所示）。如果邮件没有到达 Drop 文件夹，可使用集线器传输服务器上的队列查看器来查看 Exchange 是否正确路由了邮件。然后再调查可能会阻止集线器传输服务器与 SharePoint 服务器上的 SMTP 服务进行通信的网络通信问题。
图 4 入站邮件传输（单击此图像可查看大图）
当重新启动计时器服务时，应查看邮件项目是否已从 Drop 文件夹中消失。但是，如果邮件附件最终并未以文档的形式进入目标库（即使 SharePoint 在 Windows 事件日志中指出邮件处理成功），则说明 Exchange 是以 Exchange RTF 格式发送的邮件。要调查此问题，请再次关闭计时器服务，通过 Outlook® 客户端再发送一封带有附件的邮件，然后在其到达 Drop 文件夹后用记事本打开该邮件。在其中搜索字符串 "winmail.dat"。如果发现此字符串，则表明 Exchange 服务器是以错误的格式发送的邮件。
SharePoint 要求邮件附件必须以 MIME 或 UUENCODE 格式进行编码。而且，SharePoint 不会在 Windows 事件日志中显示任何与 winmail.dat 相关的问题处理方法（请参阅图 5）。文件附件并不出现在文档库中。使用记事本作为故障排除工具，通过在 SharePoint 电子邮件域的 Exchange 管理控制台中配置远程域定义来消除格式问题。在 Format of original message sent as attachment to journal report（作为附件发送到日志报告的原始邮件的格式）选项卡中，选择 Exchange rich-text format（Exchange RTF 格式）下面的 Never use（永不使用）。
图 5 Winmail.dat 邮件处理（单击此图像可查看大图）

目录管理
其中一个非常有用的计时器服务事件是事件 6873，它表明在处理入站电子邮件文件时由于未知别名而发生错误。如果 Exchange 用户在发送邮件时指定了一个错误的 SharePoint 电子邮件地址（例如指定了一个不存在的文档库），则会发生此类事件。
要缓解此问题，可以在 SharePoint 管理中心的“传入电子邮件设置”中配置“目录管理服务”，以便在 Active Directory 中为启用了邮件功能的文档库创建收件人对象。然后，Exchange 用户可通过地址簿中的正确地址信息来方便地选择这些收件人对象。
但是请注意，您现在正在引入一个新的可能需要进行故障排除的问题。在基于最低权限原则的安全系统配置中，“目录管理服务”将失败，因为此功能已对 Web 服务器提升了权限要求。并且，在建议您应该在 OU 中（此 OU 是您在 Active Directory 中为 SharePoint 收件人对象指定的）授予管理中心应用程序池帐户“创建、删除和管理用户帐户”权限时，产品文档（如 technet.microsoft.com/library/cc262947.aspx）有些过于强调这一点了。
“目录管理服务”会创建联系人和组对象，因此管理中心应用程序池帐户需要完全控制此 OU 中的联系人和组对象，但它不需要用户帐户的管理权限。如果您按照本文所述在 Web 场中设置“目录管理服务”并尝试为文档库启用邮件功能，则出现“访问被拒绝”错误的机率非常大。
错误信息可指出 Active Directory 的具体权限问题，并且 SharePoint 管理员会迅速为 SharePoint OU 分配 Everyone 完全控制权限。但是，这不仅会削弱 Active Directory 的安全性，而且也无助于问题的解决。
结构化的故障排除方法要求首先找到问题点，然后再采用有针对性的配置变更。如果您遵循此方法来查看域控制器上的 Windows 事件日志并使用 Network Monitor 来跟踪网络通信，您可能会发现在此问题发生时 SharePoint 并未访问 Active Directory。因此 Active Directory 配置变更不可能会修复此问题。问题发生在 SharePoint 服务器上。
不幸的是，获取更多有关此权限问题的有用信息却比较困难。SharePoint 并未在 Windows 事件日志中记录任何附加信息。但是，如果启用 SharePoint 调试功能，则会看到调用堆栈（如图 6 所示），它指出“目录管理服务”使用了某个 SharePoint Web 服务的 CreateContact 方法。SharePoint SDK 会告诉您此服务是“电子邮件集成 Web 服务”(<WSS_server>:<admin_port>/_vti_bin/SharepointEmailWS.asmx)。
图 6 调试输出
Server was unable to process request. ---> Access is denied.
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message,      WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[]      parameters)
   at Microsoft.SharePoint.DirectorySoap.SPDirectoryManagementProxy.CreateContact(String Alias,      String FirstName, String LastName, String ForwardingEmail, ContactFlags Flags)
   at Microsoft.SharePoint.SPList.UpdateDirectoryManagementService(String oldAlias, String      newAlias)
   at Microsoft.SharePoint.SPList.Update(Boolean bFromMigration)
   at Microsoft.SharePoint.SPList.Update()
   at Microsoft.SharePoint.ApplicationPages.EmailSettingsPage.SubmitButton_Click(Object sender,      EventArgs args)
   at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String      eventArgument)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean      includeStagesAfterAsyncPoint)
让我们在 Web 浏览器中看一看 SharepointEmailWS.asmx 以了解支持的操作列表。您可以在其中看到 CreateContact 方法，单击 CreateContact 链接时会显示 SOAP 消息，如果您想要在 Active Directory 中创建联系人，则必须将这些消息发送到此 Web 服务。这真是太棒了，因为现在您可以创建一个在 SharePoint 用户界面之外运行的基于脚本的故障排除工具（请参阅随附材料中的 SharepointEmailWS.vbs），从而能够在测试运行期间更方便地指定不同的用户帐户。图 7 显示了以管理中心应用程序池帐户身份（左）和 SharePoint 管理员帐户身份（右）运行此脚本时返回的信息。
图 7 两个不同的“访问被拒绝”错误（单击此图像可查看大图）
错误消息并不相同！两条消息均说明访问被拒绝，但左侧错误指出了问题处理方法，而右侧错误则没有。那么，应用程序池帐户与 SharePoint 管理员帐户之间究竟有什么不同呢？
SharePoint 管理员是 SharePoint 服务器上的本地管理员，而应用程序池帐户却并非如此。将 Web 应用程序的应用程序池帐户添加到本地管理员组并重新启动 Web 服务器可以解决此问题，但这并不是一种明智的做法。我认为在用于生产的 Web 服务器上以管理权限运行应用程序池帐户是不可接受的。
为什么应用程序池帐户需要这些提升的权限？同样，该脚本可揭示答案。如果出于测试目的授予所有用户对 Web 服务器的本地管理员权限，您会发现应用程序池帐户可以使用“电子邮件集成 Web 服务”，但所有其他帐户（包括 SharePoint 管理员）的访问仍被拒绝。这意味着“电子邮件集成 Web 服务”是使用应用程序池配置作为访问控制决策基础的。
应用程序池配置是 IIS 元数据库（或 IIS 7.0 中的 applicationHost.config 文件）的一部分，默认情况下只有本地管理员才能访问元数据库。幸运的是，也可以使用 IIS 6.0 资源工具包中所包含的 Metabase Explorer 来授予非管理员帐户访问元数据库的权限。在 IIS 7.0 中则更加简单，只需运行以下命令就可以授予对 applicationHost.config 文件的完全控制权限：
CACLS "%SystemDrive%\Windows\System32\inetsrv\config\applicationHost.config"
/G "<application pool account>" :F /E iisreset /noforce
总而言之，要想在 Active Directory 中创建联系人对象，管理中心应用程序池必须对目标 OU 中的联系人和组对象具有完全控制权限。并且 Web 应用程序的池帐户还需要对 Web 场中 SharePoint 服务器上的元数据库具有完全访问权限。现在，已经做好了一切准备，可以开始使用 SharePoint 用户界面来创建联系人对象了。
请等一下，还有其他的问题！在 Active Directory 中创建收件人对象只完成了目录集成工作的一半。另一半工作是生成与 Exchange 相关的收件人属性并更新基于服务器的地址簿。例如，如果使用 Exchange 管理外壳命令 Update-GlobalAddressList "Default Global Address List" 来更新 Exchange 服务器上的全局地址列表，则可以在 Outlook 地址簿中显示为 SharePoint 文档库新创建的收件人对象。但是在向这些收件人发送邮件时，会由于地址信息不正确而生成未送达报告，如图 8 所示。
图 8 无法将邮件递送到文档库（单击此图像可查看大图）
首字母缩写词 IMCEAEX 代表 Internet Mail Connector Encapsulated Address for Exchange（用于 Exchange 的 Internet 邮件连接器封装地址）。它使用旧有 Exchange Internet 邮件连接器能够处理的格式来表示封装的非 Exchange 收件人地址。但是现在我们处理的是 Exchange Server 2007 和基于本机 SMTP 的发送连接器。
问题的关键在于 SharePoint 电子邮件集成 Web 服务并未写入 Exchange Server 2007 传输邮件时所需的地址属性。它只写入了名字、姓氏、显示名称和目标地址（或者 ms-Exch-RequireAuthToSendTo）属性。它并未设置邮件昵称（或传统的 Exchange DN 或代理地址），也未建立收件人对象与 Exchange 收件人策略的关联。
要解决此问题，可使用 Exchange 管理外壳中的 Get-Mailbox cmdlet 来获取所有收件人对象以及指向 SharePoint 电子邮件域的目标地址。然后再将输出内容传送到 Set-MailContact cmdlet 以激活 Exchange 收件人策略，如下所示：
Get-Contact | where { $_.WindowsEmailAddress –like
  '*sharepoint.contoso.com' } | Set-MailContact
  -EmailAddressPolicyEnabled:$True
或者，使用 Exchange 管理控制台并选中联系人对象属性中的 Automatically update e-mail addresses based on e-mail address policy（基于电子邮件地址策略自动更新电子邮件地址）复选框。

WSS 3.0 和 MOSS 2007 默认支持所有消息传递集成以允许基于电子邮件的警报和通知、工作流以及文档提交。邮件集成可以提高工作人员的效率，但正确配置系统并不是一件容易的事情。尤其是您必须确保入站和出站邮件传输都运行正常。还应确保目录集成可以正常工作。
SharePoint 错误消息有时不是很直观，无法通过它了解更多的参考信息。但是，我已向您展示了深入探究集成问题、找出根本原因以及在不危及 SharePoint 服务器安全的情况下可靠消除它们的方法。

Pav Cherny 是一位 IT 专家兼撰稿人，专门研究 Microsoft 协作与统一通信技术。他的作品包括白皮书、产品手册和书籍，其内容主要介绍 IT 运营和系统管理。Pav 是 Biblioso Corporation 的总裁，该公司主要经营托管文档和本地化服务。


Windows PowerShell 远程管理 2.0 版快速浏览
Don Jones

此专栏基于 Windows PowerShell 的预发布版本。文中包含的所有信息均有可能发生变更。

目录
两种远程作业类型
同步与异步
可重用的运行空间
扇入远程作业
2.0 中的杀手级应用程序
您有没有体验过 Windows PowerShell 2.0 的最新社区技术预览版 (CTP)？最新版本的 CTP2 进一步改进了远程管理，现在是开始熟悉它所提供的新功能的绝佳时机。在开始介绍之前，您应花点时间
把它下载下来，网址为：go.microsoft.com/fwlink/?LinkID=119707。
首先，我要澄清几个要点。CTP 是 Microsoft 提供的预测试版的代码，旨在让像我一样迫不及待的用户了解 Microsoft 下一版本应用程序的发展方向。每个 CTP 里程碑或最终产品（业界都这样称呼它）可能与之前的最终产品完全不同。这是因为开发团队会收集反馈并仔细研究，然后根据这些反馈对应用程序进行改动。该方法为使用 CTP 带来了一个明显的好处和一个重要注意事项。
视频
观看 Don Jones 展示 Windows PowerShell 2.0 CTP2 中新的远程管理功能。

其好处是在使用 CTP 时，您可以在产品开发过程中提供有关反馈（通过 connect.microsoft.com 网站），而团队能够根据这些反馈即时采取行动！如果等到测试版或者更糟糕，直到预发布阶段才纳入您的反馈，处理起来就要困难得多。在 CTP 期间，任何事情都可能发生，并且在必要时，团队甚至会进行大规模的改动。
其中有个注意事项。CTP 并不适用于生产用途。当然，Windows PowerShell™ 2.0 CTP2 可能是您接触到的其中一个最稳定的预发布代码部分，但您要清楚，下一个 CTP 最终产品可能是完全不同的一个应用程序。因此请不要开始依赖 CTP2，因为下一个版本可能需要您从头开始。
请注意，CTP 无法与 Windows PowerShell 1.0 同时安装。对于理想的安装情况，系统还应同时安装 Microsoft® .NET Framework 3.5 以便启用所有可用功能。否则，一些功能将受到限制。
此外，由于 CTP 是非常早的代码，而 Microsoft 目前将大部分精力都放到了在最新操作系统（即 Windows Vista® 和 Windows Server® 2008）中运行的应用程序上。因此当前的操作系统兼容性并不代表最终发布代码也存在操作系统兼容性问题。在开发周期的后期阶段，会格外重视在旧软件中移植新功能的问题。

两种远程作业类型
在远程管理领域中，通常存在以下两种远程作业类型：扇入和扇出。扇入远程作业包括多个管理员，他们执行到单个服务器的安全外壳连接。Windows PowerShell 设计为通过一种安全的分区方式启用此功能，以便能够为客户提供对服务器的各部分的管理访问权限，例如，公司的 Exchange Server 即是如此。通过扇入远程作业，您可以采用交互的方式在远程安全地访问远程服务器上安装的 Windows PowerShell 副本（仅限版本 2.0！）。
扇出远程作业是指立即向整组远程服务器发出一组命令。这些命令从工作站并行“扇出”到服务器组。它们在每台服务器上都会执行，并且结果会以 Windows PowerShell 对象的形式返回到工作站，以便复查和处理它们。Windows PowerShell 支持两种核心的扇出远程作业技术 — Windows® 管理规范 (WMI) 和 Windows 远程管理 (WinRM)，它们首先在 Windows Server 2008 中推出，而后在 Windows PowerShell 2.0 CTP 中又有所更新。

同步与异步
实际上，Windows PowerShell 1.0 甚至也有一些基本的扇出功能，它们都与 WMI 相关。例如，您可以轻松地创建一个计算机名称数组，然后从中检索 WMI 类：
$names = @("server1","server2","server2")
Get-WmiObject Win32_OperatingSystem
    –computer $names
执行方法时（例如重启计算机）需要的操作会更多一些，因为版本 1.0 没有提供执行 WMI 方法的批量方式。但在 2.0 CTP 版本中改变了这种情况，而这应归功于 Invoke-WmiMethod cmdlet：
$names = @("server1","server2","server2")
Get-WmiObject Win32_OperatingSystem     –computer $names | `
 Invoke-WmiMethod Reboot
但是，此技术存在一个问题。它是同步的，这意味着每台计算机一次只能与一台计算机联系，并且必须等到每台计算机都执行完毕后才可以执行其他命令。但是，CTP 引入了一种全新的概念，即后台作业，这将允许在后台执行类似上面所说的命令。简单说来，只需添加 –AsJob 参数即可在后台运行 WMI 命令：
$names = @("server1","server2","server2")
Get-WmiObject Win32_OperatingSystem     –computer $names -asjob
可通过运行 Get-PSJob 来查看最终作业的状态，通过运行 Receive-PSJob 来查看作业的最终结果。（我将在以后的专栏中介绍更多有关作业管理的详细信息。）但是，Invoke-Command cmdlet 为在后台运行命令提供了更好的方式，如下所示：
$command = { Get-WmiObject     Win32_OperatingSystem }
$names = @("server1","server2","server2")
Invoke-Command –command $command     –computer $names –asjob
它实际上是将 Get-WmiObject 命令向外推送到每台指定的计算机，然后在本地执行。它的执行速度通常要快得多，并且不必依赖 WMI 远程过程调用 (RPC) 连接。相反，Invoke-Command 使用的是 WinRM，默认情况下，WinRM 使用端口 80 或 443。这些端口可轻松地导航防火墙，并且是完全可配置的。Invoke-Command 还支持用于备用凭据和限制的其他参数，允许您将数以百计的计算机作为目标，但只并行运行其中的数台。这可以避免拥堵和过度开销。

可重用的运行空间
如果打算多次远程管理给定的一组计算机，应考虑使用运行空间而非简单的计算机名称列表。在 Windows PowerShell 中，运行空间只是外壳引擎的一个实例（无论它是作为外壳控制台窗口在计算机中本地运行，还是在远程计算机中在后台运行）。启动远程运行空间非常简单：
$names = @("server1","server2","server2")
New-RunSpace –computer $names
由于运行空间也使用 WinRM，因此默认情况下它们也使用端口 80（如果指定 –UseSSL 参数，则为 443）。它们也可以接受备用凭据等。如果检索最终的运行空间对象，可将其传递给 Invoke-Command，Windows PowerShell 会将命令向外推送到这些运行空间所在的计算机中：
$command = { Get-WmiObject     Win32_OperatingSystem }
$rs = Get-Runspace
Invoke-Command –command $command     –runspace $rs –asjob
这样做的好处是只要外壳处于打开状态，运行空间就始终是活动的，因此可以很方便地针对其他命令重用它们。

扇入远程作业
运行空间也是扇入远程作业的关键所在。例如，在图 1 中，我在远程计算机上创建了一个运行空间并检索了对该运行空间的一个引用，然后又使用 Push-Runspace cmdlet 激活了该运行空间。此时，我在远程计算机上运行命令，非常类似于 SSH 或其他远程外壳实用程序所允许的那样。运行 Pop-Runspace 将返回我的原始“本地”运行空间，并且外壳提示符会帮助我随时跟踪我所在的位置。
图 1 使用运行空间在远程计算机上运行命令（单击图像可查看大图）
我所运行的具体命令顺序如下：
PS C:\>new-runspace -computer     "WIN-YFZXQMHXAWM"
PS C:\>$server2 = get-runspace -sessionid 2
PS C:\>push-runspace $server2
[win-yfzxqmhxawm]: PS C:\Windows\System32>    pop-runspace
PS C:\>
此技术被称为扇入，因为多个管理员可以同时打开同一台服务器上的远程交互式运行空间 — 他们从各自的工作站“扇入”到服务器。Windows PowerShell 2.0 中的新安全模型允许创建受限制外壳和 cmdlet，因此每个管理员均无法进行全局修改。每人都被限制在其自己的外壳区域。（这些新的安全技术需要通过以 .NET Framework 为目标的语言进行一些自定义的软件开发。此内容超出了 Windows PowerShell 专栏的范围，但最好知道存在这些功能。）

2.0 中的杀手级应用程序
Windows PowerShell 2.0 CTP 新增了一组无与伦比的功能。在我看来，远程功能即是杀手级应用程序。几乎所有环境中的每个管理员都可以从中受益。
您应当熟悉这些功能，以便向产品团队提供您的建议。您是否希望通过组策略来管理 WinRM 默认端口？cmdlet 的工作方式是否应有所不同？是否存在性能问题？WinRM 配置起来容易吗？您可以将建议发送到 connect.microsoft.com 来发表您的观点，或与 MVP 奖获者以及我本人（要与我联系，请将您的反馈发布到论坛 ScriptingAnswers.com）共享您的反馈。让我们共同参与，一起构建下一代 Windows PowerShell 的杀手级应用程序！
本月 Cmdlet：Select-Object
尝试一下：Get-Service | ConvertTo-HTML | Out-File Services.htm。现在，在 Web 浏览器中查看得到的 HTML 文件。显示的信息非常多，是不是？如果说有一种方法可以通过选择感兴趣的信息来精简页面内容的话，那这种方法就是 Select-Object。例如，如果只需要服务名称和当前状态的列表。可使用：Get-Service | Select Name,Status | ConvertTo-HTML | Out-File Services.htm。
但是，需要记住的一件事是 Select-Object 舍弃了原始对象（在本例中为服务）而生成了一个仅包含指定属性的自定义对象（实际为 PSCustom 对象类型）。该原始对象的任何功能都已无法再访问，因此您可能会希望将 Select-Object 放在管道结尾处，以尽可能处理原始对象。

Don Jones 是《Windows PowerShell v2.0:TFM》的合著者，也是 ScriptingAnswers.com“特种部队”教室培训 (scriptinganswers.com/training.asp) 的培训师。您可以通过 jeepdon@mac.com 与他联系。


您好，脚本专家！ 使用快速通道
Microsoft 脚本专家

在过去的几个月里，其中一名脚本专家在西雅图地区体验了一种在当地尚属新鲜的事物。它就是正在全美各地进行测试的一项计划，称为电子不停车收费系统。但是在华盛顿州，它被称为 Good to Go！
其工作原理如下：购买一个电子设备并将其粘贴在挡风玻璃上。还需要开设一个帐户并存入少量现金。每次经过高速公路上安装的监控设备时，费用就会自动从您的帐户划走。基本上来说，您不必在收费站停车即可支付高速公路通行费（高速公路的“免费”午餐到此为止了 — 很显然，我们需要开始改称它为高架路了，尽管最近我们看到有些高架路被水淹了好几英尺，使得它们看起来根本不像名字里说的那样高）。
目前在许多收费处，合乘汽车的人们都不必付费。但是，"Good to Go!" 最有趣的地方是它针对的只是共乘车辆专用道。您想知道这样做的目的是什么吗？难道有人会特意合乘汽车，然后又不得不为此支付费用？不错，肯定没有。此系统仅对那些单独驾驶车辆但又想使用共乘车辆专用道的人们收费。之所以想要使用共乘车辆专用道，最直接的原因就是该车道上的车辆通常很少；有时共乘车辆专用道实际上是唯一不堵塞的通道。
正如我们所提到的，此系统目前正处在试验阶段，但已经有成千上万的人报名参加。在西雅图地区，许多人都宁愿花钱使用快速通道以便到达他们的目的地。
在本月的专栏中，脚本专家们决定进行一个小实验。我们决定向您展示一个被称为 Microsoft® Visual Basic® 速成版的快速通道。首先要告诉您，此通道最酷之处是它真正免费；无论在哪里使用、有多少人使用或者是在一天中的什么时间使用，都不会收取任何费用。这听起来相当不错，是不是？当然，您也必须为此付出一点点代价，那就是需要学习一些新知识，但您应该会认为这是完全值得的。
在继续之前需要声明，我们知道我们有点越界了。通常，Visual Studio® 产品（如 Visual Basic 和 Visual C#®）都是《MSDN® 杂志》而非《TechNet 杂志》的主题。但既然 MSDN 和 TechNet 似乎都已经开始逐渐朝着成为一个大的 — 呃，融洽的 — 家庭方向发展，我们也希望能允许我们稍稍越一下界。而且，尽管我们要谈的是如何使用在传统上被视为开发人员工具的产品，但我们的交谈对象却仍是 Windows® 系统管理员。再过几分钟您就会明白我们的意思了。
您需要跟着做的第一件事就是安装 Visual Basic。不，等一等。千万不要仍给我一句“我没有！”或“我买不起”就溜之大吉。Microsoft 提供了速成版的 Visual Basic，可以从下面的地址免费下载：microsoft.com/express/download。
我们并不准备详细介绍如何使用 Visual Basic 速成版。在“帮助”中都有教程，而且“帮助”本身就非常不错。（难以相信，是不是？）我们要做的是向您演示如何使用 Visual Basic 速成版来解决 Windows Vista® 中的一个特定问题（此示例也适用于先前版本的 Windows），然后您可以自行进行深入的研究。我们要解决的问题是：如何在 Windows Vista 中打开一个文件打开对话框？
在几年前，我们曾介绍过如何通过脚本打开一个文件打开对话框（请参阅专栏“如何向用户显示用来选择文件的对话框？”，网址为：microsoft.com/technet/scriptcenter/resources/qanda/jan05/hey0128.mspx）。该文章发表在 2005 年 1 月，远早于 Windows Vista 的问世时间。该解决方案使用 UserAccounts.CommonDialog ActiveX® 控件打开一个文件打开对话框，利用它可以浏览找到要打开的文件。不幸的是，从 Windows Vista 开始，此控件已从 Windows 中被删除，这意味着此解决方案已不再适用于新系统。（不，没有人问过我们这是不是一个好主意。）至少我们知道，这意味着将无法再使用 VBScript 打开一个文件打开对话框。因此，我们并不去编写脚本，而是要使用 Visual Basic 来编写一个应用程序。此应用程序的作用之一就是打开一个文件打开对话框。
是的，没错，我们将向您展示的示例是在 Visual Basic 中构建一个完整的应用程序。刚开始听起来可能有点可怕，但您很快就会发现使用 Visual Basic 速成版构建完整的应用程序和编写脚本一样简单。此应用程序将包括一个窗口（即窗体），它允许您通过单击一个按钮来打开文件打开对话框。然后，您可以利用这个对话框选择文本文件，我们的应用程序会读取这些文本文件并在窗体中显示所选的内容。
书归正传，让我们开始动手吧。首先打开 Visual Basic 速成版。要做的第一件事就是创建一个新项目，为此我们可以从“文件”菜单选择“新建项目”。“新建项目”对话框出现。（请注意，如果使用 2008 之前的 Visual Basic 速成版，您会发现它们与本文介绍的略有差别。）我们将创建一个 Windows 窗体应用程序，因此选择“Windows 窗体应用程序”模板并为项目键入一个名称。我们将其命名为 ReadFiles，如图 1 所示。
图 1 在 Visual Basic 中新建一个项目（单击图像可查看大图）
首次创建项目时，它会自动显示一个供用户进行操作的新窗体。我们要创建的应用程序会向用户显示一个类似于图 2 所示的窗体。正如我们提到的，此窗体包括一个按钮，单击它后会显示一个文件打开对话框，可打开文件夹 C:\Scripts。用户可以选择位于文件系统任意位置的一个或多个文本文件。然后，应用程序会读取每个所选文本文件的第一行内容，并在窗体的列表框中显示结果。（如果这些听起来很熟悉，那么您很可能参加过 2008 脚本编写比赛的初级组：microsoft.com/technet/scriptcenter/funzone/games/games08/bevent3.mspx。）
图 2 将呈现给用户的 ReadFiles 窗体
要创建窗体，需要将控件从工具箱拖到项目窗体中。默认情况下，工具箱位于 Visual Basic 窗口的左侧。（如果工具箱未打开，可单击 Visual Basic 工作区左侧的“工具箱”按钮，展开所有 Windows 窗体。）单击工具箱中的“按钮”，然后在窗体中单击并拖动鼠标以创建所需大小的按钮。要为按钮添加标签，可单击刚刚添加到窗体的按钮并键入所需的标签内容。（或者，也可以编辑“属性”对话框中的 Text 属性，该对话框默认位于 Visual Basic 工作区的右下方。）我们将按钮标记为“浏览文件”。接下来，单击“列表框”，然后再次在窗体上单击并拖动鼠标来创建列表框。我们将使用此列表框来显示从文本文件中读取的各行内容。
这就是创建窗体所需的全部工作。接下来介绍有意思的部分：我们需要在单击按钮时触发某个事件。首先双击窗体上的“按钮”控件。这会打开一个代码编辑器，其中已创建好了一个新的子例程，即 Button1_Click 子例程：
Private Sub Button1_Click _
  (ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
  Handles Button1.Click
End Sub
每次单击窗体上的此按钮时都会运行这个子例程。正如您所看到的，这个子例程此时是空的；我们需要在其中添加一些代码，以告诉应用程序当单击此按钮时应执行什么操作。我们究竟想要达到什么目的呢？首先我们要做的是在本专栏开头向您承诺的一件事：打开一个文件打开对话框。几乎与要使用 Visual Basic 实现的所有功能一样，我们将使用 Microsoft .NET Framework 来实现这一目标。
首先在这个子例程的上方添加几条 Imports 语句：
Imports System
Imports System.IO
这些语句指定 .NET Framework 命名空间。我们将会用到这些命名空间中的类，因此在这里导入它们以便只需引用所需的类即可。请注意，我们说的是在子例程上方插入这些语句。Imports 语句是全局的，这意味着不能把它们放在子例程或函数的内部；它们需要单独位于外部。
在 VBScript 中，除非在脚本顶端添加了 Option Explicit 语句，否则不必显式声明变量。在 Visual Basic 中，它会自动添加，因此需要声明所有变量。我们需要使用一个变量来保存对 OpenFileDialog 对象（代表文件打开对话框）的引用：
Dim dlg As Windows.Forms.OpenFileDialog
现在已经利用 Dim 声明了类型为 OpenFileDialog 的变量，接下来可以创建此对象的新实例，如下所示：
dlg = New OpenFileDialog()
但是，我们仍未显示此对话框。首先需要设置一些属性：
dlg.Multiselect = True
dlg.InitialDirectory = "c:\scripts"
dlg.Filter = "txt files (*.txt)|*.txt|" & _
  "All files (*.*)|*.*"
Multiselect 属性可指定是否允许用户从文件打开对话框中选择多个文件。我们希望如此，因此将此属性设为 True。将 InitialDirectory 属性设为 C:\Scripts。如果不设置此属性，对话框在打开时将显示计算机的主目录。
最后（当然可以不止这些）设置 Filter 属性：
dlg.Filter = "txt files (*.txt)|*.txt|" & _
  "All files (*.*)|*.*"
我们在此处过滤要通过对话框向用户显示的文件。我们只想显示 .txt 文件。设置了这些属性后，我们将得到一个类似图 3 所示的文件打开对话框。
图 3 仅显示文本文件的“Open”（打开）对话框（单击图像可查看大图）
现在是显示对话框的最终时刻了。我们使用的是 ShowDialog 方法：
dlg.ShowDialog()
ShowDialog 方法将返回一个值，用于指出用户是单击“Open”（打开）打开所选文件还是单击“Cancel”（取消）关闭对话框。如果单击“Cancel”（取消），则不会再有任何操作。因此，我们把对 ShowDialog 的调用放在一个 If 语句中，以确保在单击“Open”（打开）后我们才继续后续操作：
If dlg.ShowDialog() = _
  Windows.Forms.DialogResult.OK Then
是的，我们知道，我们检查的是 OK 属性而非 Open 属性。在后台，“Open”（打开）按钮实际与“OK”（确定）按钮完全相同 — 向用户显示 Open 的原因只是因为它更具实际含义。
现在，我们需要知道用户从对话框中选择了哪个或哪些文件。文件名包括在 OpenFileDialog 对象的 FileNames 属性中，因此我们建立一个 For Each 循环来读取此属性中包含的文件名：
For Each strName In dlg.FileNames
天哪！我们忘记声明 strName 了：
Dim strName As String
现在我们需要打开每个文件并读取它们。在 Visual Basic 中实现此目的的方法是使用 Using 块：
Using sr As StreamReader = File.OpenText(strName)
Using 块并非 VBScript 脚本编写人员所习惯的那种，因为实际上它并不存在于 VBScript 中。Visual Basic 在管理系统资源方面比 VBScript 要好一些（好吧，就算是在许多情况下都要好很多）。Using 语句的目的是确保在我们退出块后系统资源会被释放。在目前的情况下，我们只是想确保自己不会抓着文件内容和大块的内存不放。
我们知道这听起来有点复杂。但在实际中把它看作是一个 Set 语句就可以了。我们只是为新对象（在本例中是 StreamReader 对象）创建一个实例，并将 File.OpenText 方法所返回的文本流分配给它。请注意，我们把将要打开的文件（即当前正在遍历的 FileNames 集合中的文件）的名称传递给了 OpenText。
因此，StreamReader 变量 sr 中包含了文件的内容。现在，我们还需要另一个变量：
Dim strLine As String
我们将使用此变量来存储刚刚打开的文本文件的第一行内容：
strLine = sr.ReadLine()
我们通过调用 StreamReader 对象的 ReadLine 方法来读取文件的第一行内容。（请记住，StreamReader 对象中包含文件的内容。）我们将这行文本储存到变量 strLine 中。
现在，我们只需调用 ListBox 对象的 Add 方法将此行文本添加到列表框中即可：
ListBox1.Items.Add(strLine)
在本示例中，我们需要的只是文件的第一行内容，因此可以关闭 StreamReader（我们不希望还继续抓着文本文件的所有内容不放）并关闭 Using 块：
sr.Close()
End Using
然后，我们逐一处理通过文件打开对话框选择的所有文件，直到读取完所有选中的文件并将所有行添加到列表框中为止。完整的代码如图 4 所示。
图 4 完整的 ReadFiles 代码
Imports System
Imports System.IO

Public Class Form1

  Private Sub Button1_Click _
   (ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
   Handles Button1.Click
    Dim dlg As Windows.Forms.OpenFileDialog
    Dim strName As String

    dlg = New OpenFileDialog()

    dlg.Multiselect = True
    dlg.InitialDirectory = "c:\scripts"
    dlg.Filter = "txt files (*.txt)|" & _
      "*.txt|All files (*.*)|*.*"

    If dlg.ShowDialog() = _
     Windows.Forms.DialogResult.OK Then
      For Each strName In dlg.FileNames
        Using sr As StreamReader = _
         File.OpenText(strName)
          Dim strLine As String
          strLine = sr.ReadLine()
          ListBox1.Items.Add(strLine)
          sr.Close()
        End Using
      Next
    End If
   End Sub
  End Class
怎么样，我们说过创建应用程序并不比创建脚本困难多少吧。
您可以按 F5（或按“调试”工具栏上的“启动调试”按钮）对应用程序进行测试。如果单击按钮并在文件打开对话框中选择了一个或多个文件，则结果应如图 5 所示。
图 5 在列表框中显示的所选文件的第一行内容
如果应用程序是按照您所希望的方式运行的，则从“Build”（生成）菜单选择“生成 ReadFiles”（或实际的项目名称）。这样就创建了一个名为 ReadFiles.exe 的 .exe 文件，它的运行方式与其他应用程序一样并且可以将其分发给用户使用。
我们知道这可能并不算是使用文件打开对话框的“快速”通道。但是鉴于从 Windows Vista 开始就无法再通过编写脚本来实现此目的了，那就把编写一个简单的应用程序看作是一个小小的代价吧。就像是在免费的高速公路上通行时必须要付钱才能实际到达目的地一样：可能会有点麻烦，但最终您会实现所希望的目标。
使用 Visual Basic 来编写此类应用程序的另一好处是您已经可以开始使用比 VBScript 功能更加强大的工具了，而且还可以通过友好的用户界面轻松创建一个应用程序；这也算是一个额外收获吧。系统管理员也会发现 Visual Basic 的许多其他用途。
并且请记住，您不必重新学习如何在新的收费车道上驾驶；您只需习惯于前面的汽车在一直不停地向前开这个事实就可以了。同样，如果您了解 VBScript，则不必从头学起就可以使用全新的 Visual Basic 语言了，您只需习惯它可以实现更多功能这一事实就可以了。
Scripto 博士的脚本谜题
每月挑战不仅测试您解决谜题的能力，还测试您的脚本编写技能。

2008 年 8 月用脚本编写字母表
在本月的谜题中，您需要在空白区域插入 A 到 Z 之间的字母，并最终显示一个与脚本编写有关的单词。每个字母（A 到 Z）只能使用一次，并且不能以字母排列顺序出现。插入的字母可以位于单词开头、结尾或中间的任意位置。例如，在第一行中我们插入字母 C 可以得到单词 SCRIPT：

答案：
Scripto 博士的脚本谜题
答案：用脚本编写字母表，2008 年 8 月

脚本专家为 Microsoft 工作，也就是受雇于 Microsoft。在玩、教或看棒球（以及各种其他活动）的闲暇之余，他们还负责维护 TechNet 脚本中心。要查看相关信息，请访问 www.scriptingguys.com。


桌面文件 Windows 部署服务 101
Wes Miller

目录
Windows Server 2003 中的 WDS
Windows Server 2008 中的 WDS
做出选择
注意事项
WDS 入门
捕获映像
捕获 101
映像迁移
无人参与安装
上个月的专栏回顾了 Microsoft 基于预引导执行环境 (PXE) 的部署工具的历史。本月，我们将深入研究 Windows 部署服务 (WDS)，具体讨论随 Windows Server 2003 提供的版本以及随 Windows Server 2008 提供的更新版本
。之后，我向您演示使用 WDS 运行。
WDS 最适合被视为重新编写的远程安装服务 (RIS)。尽管它们共享一些关键组件，而且实际上 Windows Server® 2003 中 WDS 版本的旧模式在功能上与 RIS 相同，但以本机模式运行与以 50% 的混合模式运行的 WDS 实际基础结构都是全新的。

Windows Server 2003 中的 WDS
WDS 随着 Windows Vista® 的发布一共问世。这一步骤是非常必要的，因为 Windows Vista 安装程序是使用 Windows® 映像格式 (WIM) 体系结构彻底重新设计的，使得 RIS 无法部署 Windows Vista（甚至是 Windows Server 2008）。因而将 WDS 作为带外版本，供运行 Windows Server 2003 SP1 的客户下载。在 SP2 中，RIS 已完全被 WDS 所取代。
您应记住，由于 Windows Server 2003 中的 WDS 完全向后兼容，因此当您在 Windows Server 2003 SP2 系统中安装 WDS 时，不必移到本机模式。您可以继续在旧模式（做为 RIS 服务器履行功能）或混合模式下运行，允许启动 WDS 或 RIS。
除了能够部署 Windows Vista 和 Windows Server 2008 以外，以本机模式或以 50% 的混合模式运行的 WDS 还具有若干其他功能。WDS 使用 Windows PE 作为其启动预安装环境，而不是利用我上月讨论的 Windows 内核模式安装引擎和传统的安装程序核心 (technet.microsoft.com/magazine/cc645015)，而且它部署基于 WIM 的映像，而不是使用基于 RISetup 或 RIPrep 的安装。这样部署得更快、更简单且更可靠。
此外，由于 Windows PE 可以显示与 Windows 完整安装相同的字符集，我上月介绍的许多限制（例如，需要使用基于“美国国家标准协会”(ANSI) 的字符）已不复存在。
另外，WDS 还获得了 RIS 不具备的几个工具（用于协助管理的 Microsoft® 管理控制台 (MMC) 管理单元）以及极其全面的命令行配置工具（使配置功能远远超过 RIS）。
由于旧模式和混合模式均允许部署 Windows 基于 RISetup 和 RIPrep 的映像，因此您需要牢记一件事情。RIS 以前一直使用名为单实例存储 (SIS) 的组件来优化磁盘上的映像存储。之后随 Windows Storage Server 2003 提供的 SIS 利用了一项名为 Groveler 的服务，它在 RIS（以及 WDS）服务器的后台运行，用于查找相同的文件。如果任何文件的大小和哈希都匹配，则 SIS 会将副本复制到其自己的 SIS Common Store 文件夹中，然后创建指向其找到的每个原始版本的硬链接。
SIS 旨在最大程度地减小对处理器利用率的影响，同时节省大量存储空间。这一出色的概念由 RIS 首次使用，之后广泛应用于 Windows Server 平台。但之后的 WDS 不再使用 SIS。
由于 Windows Server 2003 中以本机模式运行的 WDS（并且常常是在 Windows Server 2008 上运行）利用 WIM 映像进行安装，因此它具有其自己的压缩以及（更重要的是）自己的单实例文件存储模型，它根本不使用 SIS。“映像存储”将 RIS 使用的存储模型替换为 WDS 基于 WIM 的新设计。如需 SIS 的详细信息，请访问 go.microsoft.com/fwlink/?LinkId=120302。

Windows Server 2008 中的 WDS
在 Windows Server 2008 中，WDS 已成为 Windows Server 2003 中功能的扩展集和子集。它现在可以使用传输服务器在独立模式下通过多播部署映像，传输服务器是一种全新的简单文件传输协议 (TFTP) 服务器，它的性能更好、支持基于可扩展固件接口 (EFI) 的 x64 系统，并具有增强的安装指标报告。我将在下月的专栏中对此加以介绍。
请注意，Windows Server 2003 中的 WDS 有一个功能在 Windows Server 2008 中已不再提供，即旧安装支持。不再提供部署 RISetup/RIPrep 映像或使用旧 RIS OS Chooser 启动安装的功能。

做出选择
自 Windows Server 2008 发布后我经常会遇到的一个问题是：“我应该使用哪一个版本的 WDS？”答案取决于您是否部署的是早于 Windows Vista 的版本，如果是，还要看是否已经准备好从基于 RISetup 和/或 RIPrep 的映像过渡到明确使用基于 WIM 的安装。
即使在 Windows Server 2008 中，WDS 也始终可以将 Windows 部署回 Windows 2000（如果它在 WIM 映像中），而且可以使用多播完成此操作。因此，如果您要立即从 RIS 过渡到 WDS，想想您基础结构中的 Windows Server 2008，如果您愿意从基于 RIS 的映像迁移到基于 WDS 的映像，那么迁移到 Windows Server 2008 中的 WDS 可能对您比较适合。
还可以在 Windows Server 2003 系统本身从 RIS 迁移 WDS（当您安装 SP2 时，基本上就会发生这一情况），再过渡到基于 WDS 的映像。然后，您只需升级到 Windows Server 2008 WDS 即可。
但我并不建议使用这种模型。与 2008 之前的许多 Windows Server 版本一样，Microsoft 建议从一个版本的 Windows Server 迁移（比照就地升级）到另一版本的 Windows Server。
正如我之前提到的，对于您的基础结构而言，考虑使用 x64 版本的 Windows Server 2008 可能比 x64 版本的 Windows Server 2003 更有意义。如果确实要进行这种转换，与就地升级相比，对 WDS 执行从 Windows Server 2003 到 Windows Server 2008 的服务器到服务器迁移将相对容易些，而且更为可靠。

注意事项
您在部署 WDS 时有几点需要牢记。请注意，它们实际上并不是 WDS 的新要求（RIS 也有许多相同的注意事项），但无论是构建单 WDS 服务器还是整个基础结构均应将其考虑在内：
权限 当您管理 WDS 服务器时需要牢记两个主要项目。必须在 Active Directory® 中对 WDS 服务器授权，就象您对 RIS 所做的处理一样。为此，您必须是林根域的域管理员（企业管理员）或者您必须被委派了相应的权限。要管理您的 WDS 服务器，您需要是域管理员，当然，您还必须是 WDS 服务器本身的管理员。
虚拟化 如在 Microsoft Virtual PC 或 Virtual Server 下虚拟化的 Windows Server 2003 或 Windows Server 2008 实例上运行，并与安装相同 Virtual PC 或 Virtual Server 的客户端 PC 通信，可能会在开始 PXE 引导时出现争用，导致客户端的速度非常缓慢或者挂起。建议您虚拟化客户端或服务器，但不要两者同时虚拟化，尤其是在同一主机系统上。从个人角度来讲，我不建议虚拟化要用于生产的 WDS 服务器，原因如下所述。
其他服务 和 RIS 一样，WDS 与其他生产服务的配合并不能始终保持令人满意。具体来说，在运行 Microsoft Exchange Server、Systems Management Server (SMS) 和 System Center Configuration Manager (SCCM) 的生产系统中，我曾经见过所运行的 RIS/WDS 出现问题。
一般而言，如果您将 WDS 用于大多数客户端的生产，我建议让 WDS 成为您服务器上的唯一角色。但 WDS 并不是只能有这一种状态，您应认真考虑您是否应混合 Windows 服务器产品的角色并在部署前对其进行测试。
低或高延时链路 与 RIS 一样，WDS 不适合在低带宽连接或高延时连接（如卫星链接）条件下使用；PXE 握手可能会出现问题，而且下载映像可能很费力（如果有）。

WDS 入门
WDS 的更多信息

  • Windows Server 2003 中的 WDS 分步指南
  • Windows 部署服务分步指南 (Windows Server 2008)
  • 在 Windows Server 2003 上部署和管理 WDS 更新
  • Windows Server 2008 中的 Windows 部署服务文档
  • 技术参考：Windows 部署服务 (Windows Server 2008)
首先，您必须决定是要在 Windows Server 2003 上还是 Windows Server 2008 上使用 WDS。如果使用 Windows Server 2003，我建议采用 SP2，WDS 是它自带的一个选件，而不是使用 SP1 和 Windows 自动安装工具包 (WAIK) 中之前提供的可选 WDS 下载项。
无论是哪个版本的 Windows Server，您都希望构建自己的服务器系统。您应使用高质量网络接口卡 (NIC)，速度至少能够达到 100Mbps 或者更快。请不要使用 NIC teaming，因为 WDS 的 PXE 基础结构在使用 NIC teaming 时可能会出现问题。请注意，如果您使用 Windows Server 2008，则可以将 WDS 安装在两种模式的 Windows Server 2008 上（Server Core 安装或完整安装）。
WDS 是作为一个可选组件（就象之前的 RIS）安装在 Windows Server 2003 上的。您可以在安装操作系统期间或之后安装 WDS，方法是：运行“添加/删除程序”|“添加/删除 Windows 组件（或者从命令行运行 sysocmgr.exe）。在 Windows Server 2008 中，WDS 是作为一个角色安装的，可通过初始配置向导（单击“添加角色”|“下一步”| 并选择“Windows 部署服务”）、通过服务器管理器（与初始配置向导的步骤相同）或从命令行运行 ServerManagerCmd 来安装 WDS。
安装完 WDS 后，您需要对其进行配置。在 Windows“开始”菜单下，转到“管理工具”并选择“Windows 部署服务”。MMC 启动后，右键单击您的服务器，然后从菜单中选择“配置服务器”以启动配置向导。
如果要在 Windows Server 2003 上进行安装并升级现有 RIS 服务器，您将需要指定现有 RemoteInstall 目录，以便可以将旧安装升级到混合模式。在这种情况下，应确保 RemoteInstall 目录不在系统分区上，以免会影响性能。
图 1 显示了在配置向导完成之前 Windows Server 2008 上的 WDS 控制台。图 2 显示了 Windows Server 2008 上 WDS 配置向导的“欢迎”页面。图 3 显示了 WDS 配置向导的 PXE 配置步骤。在这一步骤中，您可以指定服务器是应响应任何客户端（对于初始扩建特别有用）、仅响应已知的客户端计算机（已在 Active Directory 中预置的计算机）还是响应所有客户端（以及它是否应选择性地保留所有未知客户端，以便管理员可以选择进一步的行动方案）。
图 1 已安装但尚未配置的 WDS
图 2 WDS 配置向导
图 3 为 PXE 服务器选择响应策略
图 4 向您显示了 Windows Server 2008 上配置完整的 WDS 服务器（尚未安装任何映像），并且其“属性”页面已打开。如果您使用的服务器是动态主机配置协议 (DHCP) 服务器，确保将“DHCP 选项 60”设置为 PXEClient 并将 WDS 设置为“不侦听端口 67”。这样，您的 WDS 服务器即可在 PXE 发现过程中跳过某个步骤（如我在上月的专栏中所述）。
图 4 Windows Server 2008 上配置完整的 WDS 服务器
此向导完成后，您可以添加新的映像。在以混合模式或本机模式运行的 WDS 服务器中，可以添加两种映像：
  • 引导映像：这些映像包含 Windows PE 2.x，通常是从 Windows Server 2008 或 Windows Vista SP1 安装 DVD 中复制下来的。请注意，如果您使用多播，则对于引导映像，您将需要使用 Windows Server 2008 中的 \Sources\Boot.wim 文件（即使您部署的是 Windows Vista 或旧操作系统也是如此）。引导映像通常包含 Windows PE、Windows Setup.exe 以及其他依赖项。
  • 安装映像：这些映像由 Windows OS 映像组成，通常是 Windows Vista 或 Windows Server 2008 中的 \Sources\Install.wim 文件。
要添加默认引导映像或默认安装映像的步骤几乎是相同的。首先都要右键单击映像类型，然后选择添加该类型的映像。
对于安装映像，您需要指定映像组的名称（假设 Windows DVD 上的默认 WIM 含有多种 OS）。然后浏览到要添加的相应 boot.wim 或 install.wim 并单击“打开”。对于安装映像，您随后可以取消选中不想添加到 WDS 服务器中的任何卷映像（OS 映像）。最后，您可以使用这些默认映像以 PXE 方式安装客户端。

捕获映像
为了创建自定义 OS 映像，您需要创建一个捕获映像（即 Windows PE 映像，旨在允许您将 Windows 系统捕获为 WIM 映像）。最简单的做法是使用之前安装的 boot.wim 映像。
右键单击所需的映像，然后单击“Create Capture Boot Image”（创建捕获引导映像）。指定要用于映像的名称和说明，并指定一个位置，部署捕获映像时如发生网络连接问题，会在该位置保存 .wim 文件的本地副本。然后完成向导并单击“Finish”（完成）。
接下来右键单击 WDS MMC 中的 Boot Image 文件夹，并单击“Add Boot Image”（添加引导映像）。与先前一样，按照向导中的说明执行操作。完成后，您就可以捕获 Windows 安装映像。

捕获 101
在捕获操作系统映像之前，您必须安装 Windows 并确保其包含所有需用的应用程序、自定义和更新。下一步要做的就是在您的系统中运行 Sysprep；您只能从使用 Sysprep 准备的系统中捕获 Windows 安装映像。您必须指定有效的本地位置来保存新映像（以避免可能的损坏）和 *.wim 文件扩展名。
在配置完系统并将正确版本的 sysprep.exe 复制到系统之后，您必须执行下列步骤：
  1. 使用参考计算机上的命令提示符切换到 sysprep.exe 所在的目录。
  2. 启动 Sysprep（也可以双击 sysprep.exe 并手动指定选项）。在运行 Windows Vista 或 Windows Server 2008 的计算机上，运行命令 sysprep /oobe /generalize /reboot。在运行早期版本 Windows 的计算机上，运行 sysprep -mini –reseal –reboot。
  3. 计算机重新启动后，PXE 会对其进行引导（此过程可能因客户端系统而异）。
  4. 从引导菜单选择 WDS 捕获映像，然后单击“Next”（下一步）。
  5. 为映像选择驱动器以及名称和说明。
  6. 如前所述，将仅显示已执行过 sysprep 的系统。这是设计要求，无法更改。
  7. 单击“Browse”（浏览），然后浏览到要存储捕获的安装映像的本地文件夹。所选的位置可以是映射的网络驱动器。
  8. 选择“Upload image to WDS server”（将映像上传至 WDS 服务器）。
  9. 键入 WDS 服务器的名称，然后单击“Connect”（连接）。
  10. 从“Image Group”（映像组）列表中，选择要将映像存储在其中的映像组，然后单击“Finish”（完成）。
该映像现在已准备好从 WDS 服务器进行部署。如果您熟悉 RIS，可能已经注意到我并没有实时捕获此 Windows 映像。WDS 要求被捕获系统脱机。
在 RIS 中，RIPrep 可以捕获（实际上是要求）联机系统。该过程非常脆弱。我认为您将会找到相对简单且更为稳定可靠的 WDS 捕获过程。

映像迁移
如果您一直都在使用 RIS，那么您已经部署了一些映像。对于基于 RISetup（脚本式安装）的映像，这已经是终点。但您可以将 RIPrep 映像迁移到基于 WDS WIM 的映像。实际上，WDS 甚至允许您通过 WDSUtil 迁移映像（我将在下个月对此进行更为详细的说明）。
只有您在不想丢失的映像中投入了大量的时间时，我才会建议这样做。此过程效果很好，但我听说在转换期间发生了一些错误，这通常意味着您必须从头开始重建映像。

无人参与安装
用我先前的方法创建映像后，您可以手动进行安装。对于自动化程度更高或完全自动化的安装，您需要使用两个无人参与的安装文件。WDS 本身需要一个应答文件（unattend.xml，存储在 WDS 服务器的 \RemoteInstall\WDSClientUnattend 目录下），用于自动化 WDS 安装过程。第二个文件是实际映像无人参与文件。对于 Windows Vista 或更新版本，此为 unattend.xml 文件。对于早期版本的 Windows 映像，此为 sysprep.inf 文件（存储在 $OEM$ 目录结构中或存储在每个映像目录的 \Unattend 下）。此文件用于在 WDS 完成后自动执行 Windows 的实际安装。
要创建 WDS 无人参与文件，请使用 WAIK 为 WDS 创建一个 unattend.xml 文件。将此文件复制到 RemoteInstall 目录或子目录中。右键单击要对其使用此无人参与文件的安装映像，然后单击“属性”。在“客户端”选项卡中，请选择“启用无人参与安装”并提供之前指定的 unattend.xml 文件。
要为 Windows Vista 之前的映像创建映像无人参与文件，请将 sysprep.inf 文件复制到该映像的 $OEM$ 目录中，例如，D:\RemoteInstall\Images\Windows XP\SP2\$OEM$\$1\sysprep\sysprep.inf。对于 Windows Vista 映像，请指定要关联的映像，单击“属性”，然后在“常规”选项卡下，单击“允许在无人参与模式下安装映像”。然后指定要用于安装的 unattend.xml 文件。
至此我们已经完成了一半工作。本专栏为您介绍使用 WDS 运行。下个月，我将深入介绍 WDSUtil、映像存储细节以及多播的详细信息。之后我将深入探讨如何以及为何您会考虑在 WDS 之上构建自定义部署解决方案。目前请查看本专栏的“WDS 更多信息”侧栏。

Wes Miller 是位于德克萨斯州奥斯汀市的 CoreTrace 公司 (www.CoreTrace.com) 的高级技术产品经理。在此之前，他在 Winternals Software 公司任职，并曾在 Microsoft 担任项目经理。可通过电子邮件 technet@getwired.com 与 Wes 联系。


安全观察 密码和信用卡，第 2 部分
Jesper M. Johansson

内容
伪多因素登录过程
浏览器加载项问题
认证标记永远不能改变
降级到低安全性密码
忽略伪多因素登录
密码被破坏问题
一些好处
通过表面假象误导用户
打开还是不打开
提供安全通信
关于隐私
在这个由三部分构成的系列文章中，介绍了 IT 行业在安全性问题方面是如何给消费者带来困惑而不是为他们带来帮助的，您现在阅读的是其中的第二部分。在 2008 年 7 月刊的《TechNet 杂志》中，我介绍了不可行和不正确的安全建议以及一些令人困惑的登录工作流。（如果您尚未阅读第 1 部分，可在以下地址找到它：
technet.microsoft.com/magazine/cc626076。）在文中我阐述了我的观点，指出那些虽然相当常见但又糟糕之极的安全建议和登录工作流是如何给消费者带来困惑并削弱他们在保护个人信息方面所做的努力的。
在这一部分中，我将通过一些取自消费者安全领域的真实示例继续展开讨论。本系列文章的最后一部分将在下一期的《TechNet 杂志》中推出，其中会包括针对全球安全问题专业人员提出的倡议。

伪多因素登录过程
2005 年 10 月，美国联邦金融机构监管委员会 (FFIEC) 颁布了“网上银行环境中的身份验证”指导原则（请参阅 www.ffiec.gov/press/pr101205.htm）。实施期限只有 14 个月，因此美国的各金融机构很快就着手研究如何满足这些新的指导原则。
大多数机构都无法满足这一时间要求。许多机构虽然最终确实满足了这些指导原则，但他们所采取的措施只是为了满足这些指导原则，此外再无其他用途。换句话说，这些机构所采取的措施根本无法使客户更加安全，他们只是在进行“安全性表演”而已。其中一些最有趣的无用解决方案示例就是试图创建实际上并不具有多因素的多因素身份验证解决方案。
例如当用户键入密码时测量键入节奏的技术。在网站上使用时，此解决方案所显示的登录对话框外观与旧的登录对话框完全相同。但是，此对话框现在是一个 Adobe Flash 对象。
这个 Flash 对象会记录用户的键入节奏，包括按键的时长和两次键入操作之间的间隔等特征。此数据将与密码一起提交到网站，并与其中存储的值进行比较。键入节奏数据必须处于所存储数据的特定方差范围内，并且密码也要匹配，这样才可以成功登录。大致的想法是这样做可以允许站点使用伪生物身份验证方法，而又无需在客户端安装第三方硬件。
我将其称为伪多因素身份验证。它并不是真正的多因素身份验证方法，真正的多因素身份验证要测量两个或更多个以下规范因素：
  • 用户持有的证件（如智能卡）
  • 用户知道的信息（如密码）
  • 用户特有的标记（如指纹）
伪多因素身份验证在身份验证过程中实际上并未包括多个因素，它只是从一个因素（即密码）读取多个参数。然后，它使用这些额外参数来推断用户的身份。
伪多因素身份验证所采用的技术有许多缺陷。这些缺陷集合在一起，导致该技术根本就不可能解决它想要解决的安全性问题。

浏览器加载项问题
伪多因素身份验证系统依靠浏览器加载项来提供所需的复杂客户端处理。所有软件不可避免地都存在着错误，有些错误可能会导致出现漏洞。当软件难以更新且用户不确定是否已安装更新时，这些漏洞就会变成实实在在的问题。
浏览器加载项恰好是导致这两个因素的罪魁祸首 — 它们难以更新并且没有向用户提供足够的信息来指明所安装版本是否已是最新版本。结果导致用户必须向 Internet 公开本来可能并不需要公开的软件片段。
在某些情况下，要使加载项始终保持最新，需要定期访问该加载项的网站以获取更新。毫无疑问，对大多数用户而言这都是不太可能做到的。任何系统如果要求最终用户向 Internet 公开额外的不相关软件而仅仅是为了提供安全性功能，则有必要对其进行重点审视。

认证标记永远不能改变
对于“您特有的标记”这一因素，它具有一个并不会左右其他两个因素的特征（或者说是缺点）。您可以更改密码（您知道的信息）并且可以制造新的安全令牌（您持有的证件），但您可以使用的生物认证标记其数量却非常有限。以指纹为例，您一生中通常只能有十个认证标记。如果意外丢失了其中一个，通常是无法更换的。
现在看一看它是如何应用到伪多因素登录示例的。作为其他因素的一部分而收集的指标无法方便地进行更换或修改。毫无疑问，密码改变时，用户键入的方式会改变，但在键盘上按键时的常规方式却不会改变。这正是此方法赖以存在的基础。如果这些指标遭到破坏，完全可能重新合成它们。最起码，攻击者可以捕获这些指标并重放。

降级到低安全性密码
使用长密码并经常更改密码是一个好办法。并且，正如在本系列文章的第 1 部分介绍的，记录密码（当然是以一种安全的方式）也是一种比较好的做法（这与某些建议相左）。但是，上述方案并没有做到有助于手动键入密码。长密码通常难以键入，如果可以复制和粘贴密码，则记录的密码会更加有用。如果维护上百甚至更多密码，其中一个好方法是使用 Password Safe（网址为 sourceforge.net/projects/passwordsafe）之类的软件实用程序。通过使用此类工具，您可以生成完全随机的密码、以加密格式将其存储下来并可以直接将其粘贴到登录对话框中。实际上，在使用此类工具时，您甚至不必知道密码究竟是什么。
但难题是：无法测量键入节奏，除非用户手动键入密码。而且如果必须将密码键入测量键入节奏的对象中，则这一用来管理密码的方法会无法继续工作。正确键入包含 15 个字符且完全随机的密码并非易事。因此，在面对此类系统时，用户通常会选择简化密码。然而，一个包含 15 个字符且完全随机的密码本身要远比较短的密码与伪多因素身份验证系统相结合更加安全。
实际上，以排他方式实施的伪多因素身份验证方法会迫使用户采用低安全性的密码。不幸的是，正如您稍后将看到的，使那些使用适当密码管理方法的用户迁就伪多因素身份验证系统，会在实际当中消除它所能提供的全部价值。

忽略伪多因素登录
即使站点的确实施了伪多因素身份验证，它仍然必须支持忽略伪多因素系统的方法。首先，很少有站点会要求所有用户都必须在安装“第四方”技术后才能进行访问。部分用户（例如《TechNet 杂志》的一些作者）一直拒绝安装此类软件。
其次，键入节奏可能会由于多种原因而发生改变，因此站点必须能够适应这一点。例如某个用户因手腕扭伤而导致键入节奏临时发生了改变。如果站点分析了她的节奏后认为是其他人正试图使用她的用户凭据来登录，那么她该如何访问此站点呢？如果损伤是永久性的，用户可以重设存储的节奏值。但如果是临时损伤，假设她的键入节奏很快就可以恢复，用户可能并不希望重设存储值。
最后，并非所有用户都能够使用伪多因素身份验证系统。例如，通过语音识别界面与计算机交互的残障人士可能无法填写对话框（具体要取决于它是否允许编程输入）。此时，法律可能会强制要求提供可满足残障人士需要的备用系统。
满足所有情形的最简单而又最直接的方法是同时支持标准的基于密码的身份验证。

密码被破坏问题
伪多因素身份验证系统声称能够解决与基于密码的身份验证相关的各种问题。但是，这些系统无法完全解决可能会使密码被破坏的各种主要方法。有五种主要方法可能会使在依靠基于密码的身份验证系统中密码被破坏，在这里“被破坏”表示攻击者已获得并使用其他用户的密码：
  • 密码猜测
  • 击键记录器
  • 网页仿冒攻击
  • 询问用户
  • 侵入存储密码或其哈希值的系统
密码猜测已经不再是特别常见的攻击方法了，由于击键记录器和网页仿冒的出现它已变得相形见绌。密码猜测也是唯一由于伪多因素身份验证的出现而有所减少的攻击方法。传统的密码猜测方法不太可能适用于伪多因素身份验证系统，因为攻击者必须同时猜测密码和键入节奏。尽管从理论上说可以合成键入指标，但通常没有这样做的必要，因为可改用网页仿冒攻击或击键记录器来捕获实际数据。此外，如果系统还提供标准的仅密码登录界面，则攻击者可以使用该系统来猜测密码。
强密码可以有效地杜绝密码猜测攻击。如果可以说服用户使用更强的密码，或者再加上工具的帮助，则根本无需使用伪多因素身份验证。（相比而言，由于伪多因素身份验证系统使用的密码通常较为简单，因此客观上使密码猜测成为一种更可行的方法。）因此，任何旨在提供减少可能的密码猜测攻击的方法，只有在取消了对仅密码登录支持的情况下才能真正发挥作用。并且正如我所指出的，这种情况即使可能也非常罕见。换句话说，如果用户在伪多因素身份验证系统中使用较弱的密码，密码猜测可能会再次成为一种可行的攻击方法；这会导致伪多因素身份验证不但不能增强安全性，反而会降低安全性。对此问题需要进行更深入的研究。
伪多因素身份验证也无法解决击键记录器问题。尽管我并不清楚目前常见的击键记录器能否捕获键入节奏，但肯定不存在能够迫使人们不设计此程序的原因。击键记录器是键盘和计算机之间用来捕获击键内容的一个硬件或一款软件。在这两种情况下，记录器均对伪多因素身份验证解决方案使用的所有数据具有完全访问权限。
实际上，击键记录器甚至可以访问更多的数据，因为身份验证解决方案是以用户模式运行的，而击键记录器要远在它之下。如果在键盘与用来捕获密码的基于 Web 的对象之间没有受信任路径，则不可能防止此类攻击。如果伪多因素身份验证解决方案变得十分常见的话，肯定有人会设计此类击键记录器。
同样，伪多因素身份验证也无法解决网页仿冒攻击问题。攻击者可能会使用一个 Flash 对象来捕获密码以及键入节奏，而不是只使用一个伪造的登录屏幕。
当然，如果攻击者所使用的方法只能获取用户的密码，则伪多因素身份验证确实可以起到作用。例如，从用户获取密码的最简单方式是询问用户。令人震惊的是，无论是当面、通过电话还是通过网页仿冒邮件进行询问，这都被证实是一种非常有效的方式。
当然，询问用户的键入节奏是不太可能的。同样，如果公司密码数据库遭到破坏，则攻击者只可能会窃取密码。但是同样，只有当系统不提供标准的仅密码身份验证时，才可以减少此类攻击。
还应指出的是，如果密码数据库本身已遭到破坏，则攻击者可以采用更深入的方式来破坏系统，而不仅仅是使用单个（或即使多个）常规的用户帐户密码那样简单。因此，试图减轻侵入了密码数据库的攻击者所能实施的破坏并不会起到明显效果。

一些好处
平心而论，伪多因素身份验证确实有助于解决一些问题（假定系统不提供标准的仅密码登录选项）。例如，它可用于防止密码共享。但是，如果系统允许多个用户共享帐户（例如联合银行帐户），则这可能会成为系统的一个缺陷。
此外，正确构建的交互登录对话框（不是网站登录）在用户键入节奏不匹配时可能会强制其执行其他身份验证步骤。这可以为高敏感环境中的被破坏帐户提供额外的安全性。

通过表面假象误导用户
迷惑用户的一个最好办法就是提供不准确的安全指示。最常见的可能是网页上显示的挂锁图像，如图 1 所示。此页面甚至在挂锁旁显示了“安全”一词。
图 1 挂锁图标被滥用的一个示例，此趋势有点令人担忧（单击图像可查看大图）
您肯定知道，仅在页面上放置一个挂锁图像和“安全”一词并不能保证它的安全。但是这种现象却极其常见，甚至一些著名的专门网站也是如此。结果许多用户都养成了习惯，他们只是在网页中查找这些视觉上的安全符号，而不是查看这些符号真正能够代表某种意义的位置：在地址栏中。（W3C Web Security Context Wiki 中有一条有关此问题的说明，网址为 w3.org/2006/WSC/wiki/PadlockIconMisuse。）
不幸的是，仍存在许多类似的滥用示例。研究表明，用户根本无法识别恶意网站，即使是在证书非常明显的情况下（请参阅 www.usablesecurity.org/papers/jackson.pdf）。这取决于轻松辨别真伪的能力，即使是在没有真品可供比较的情况下。这需要一定的技巧，但网页上华而不实的安全误导内容阻碍了该技巧的发展，因为用户都被错误信息吸引过去了。
图 2 显示了有关此问题特别麻烦的一种变体。在这种情况下，显示信息的页面实际上并不安全。如果看一下地址栏，您会看到表明协议的 "http"。此站点使用了一种非常常见的优化技术 — 只加密表单提交，而不加密包含登录表单的页面。就像页面所声明的那样，登录是安全的，前提是要把“安全”等同于“加密”。但是至关重要的一点是，用户在发送凭据之前无法确认其发送目的地！此站点在提交表单之前并不向用户显示验证站点的证书。这是一场信任游戏，就像您在向后倾倒时认为后面的人会接住您一样。等到提交表单的时候，可能已经造成了损害。
图 2 不安全页面上的安全性假象（单击图像可查看大图）
安全套接字层 (SSL) 是在 HTTPS 中提供安全性的协议，主要有两个目的。首先，它为用户验证服务器。其次，它提供一个简单的机制来协商可以在客户端和服务器之间使用的会话加密密钥。
如果只加密实际的表单提交，则并未满足第一个（也是最重要的一个）目标。使用此优化技术的站点只是将 SSL 用作协商密钥的一种方法。令人啼笑皆非的是，只需使用标准的密钥协商协议就可以实现此目的，这样还可以避免因使用 SSL 所带来的成本和开销。
图 2 所示的站点并不罕见。许多站点仅为表单提交而不是为表单本身提供 SSL 保护。但是，这个特定站点有一个让人非常头疼的特点。如果在浏览器地址栏中键入 https://www.<site>.com（请注意安全 https 指示符），站点会将您重定向到非 SSL 版本的站点！即使尝试在向站点发送凭据之前先检查证书，站点还是会拒绝显示证书。
虽然并非所有站点都这么差劲，但这样的站点也不少。美国两家最大的信用卡发行公司都有此类问题。实际上，在我打过交道的三家主要信用卡公司中，只有美国运通公司对登录表单提供了证书。美国运通甚至将 HTTP 请求重定向到了 HTTPS。做得不错！
最后一个想法是与毫无意义的安全假象以及缺少登录表单证书有关的。您可能想知道为什么站点要这么做。原因很简单，可以从经济学方面加以解释。呈现证书需要加密页面，而加密页面会增加处理开销。处理开销意味着提供相同负载需要更多的计算机。计算机越多，成本就会更高。不幸的是，当需要在保护客户隐私和增加利润之间做出选择时，许多组织都会选择增加利润。

打开还是不打开
最近，我从健康保险公司处收到了一封令人惊讶的电子邮件。使用计算机超过 10 年的人都知道不应打开一个未经请求的电子邮件附件。所以可以想见我收到图 3 所示的邮件时有多么吃惊。
图 3 包含“安全附件”的电子邮件（单击图像可查看大图）
显然，我曾在健康保险公司的网站上提出过问题（直到收到这封可疑邮件我才想起是有这么一回事）。以下是该公司的答复。刚开始我以为这是一个聪明的网页仿冒欺诈。当我意识到这是一封合法的邮件时，我脖子后面的汗毛都竖起来了。
在邮件开头指示用户双击附件开始解密邮件。安全性社区和 IT 管理员花了近 10 年的时间来教会人们千万不要双击附件。然后一个公司跳了出来（顺便提一句，我的医疗保健提供商并不是使用这种方法的唯一组织）说我必须双击附件才能实现安全性。这时用户该怎么办？他应该记住或忘记哪种行为？
接下来，我使用 Microsoft® Office Outlook® 2007 中的预览功能进行查看。如图 4 所示，Outlook 认为该邮件可能是攻击邮件，警告我不要打开它！
图 4 Outlook 2007 认为该安全文档是恶意的（单击图像可查看大图）
对于健康保险公司违反全球最流行的电子邮件客户端所使用的基本安全检查这一点，让人觉得既是个讽刺又令人感到悲哀。鉴于此家公司甚至没有专门通过 Outlook 来测试新的安全性解决方案，我迫切想知道它采取了其他哪些措施来保护我的隐私信息。或者更坦率一点，我想知道它究竟实施了哪些其他解决方案来避免由于未能充分保护客户隐私而受到指控？这一点类似于财务机构所做的安全性表演。通过这件事，我认为解决方案的主要目的是避免指控 — 而不是真正保护客户。
我想看看附件到底是什么。结果发现它是一个 ActiveX® 控件对象。为了查看这个附件，我不得不在 Internet Explorer® 中打开它并安装此对象。它显示了如图 5 所示的安全屏幕。正如您所看到的，设计人员竭力使邮件看起来像一个普通的邮政信封；它甚至还包含一张邮票，声称信封是受信任的。
图 5 安全文档显示了一个标记为“受信任”的信封（单击图像可查看大图）
此类技术令人担忧的原因有多种。首先，它会使用户方养成一个非常不好的习惯：打开未经请求的附件。其次，在实际的邮件中，它给出了一种非常不负责任的做法，就是将系统配置为不经提示直接打开附件。第三，面对计算机提示的矛盾信息（即电子邮件说它是受信任的，而 Outlook 说不是），邮件看起来非常可疑。最后，实际的附件包含了一个毫无意义的安全假象，让用户确信它是受信任的。如果用户信任此类邮件，很可能也会轻易信任具有类似外观的其他恶意邮件。

提供安全通信
不可否认，此技术打算解决的问题非常重要。以一种受信任的方式与客户通信非常困难。然而，这个特殊的解决方案有点超工程设计了。它很可能会使客户产生困惑并可能最终导致与原来的目标相反的结果：客户系统遭到破坏。
经过精心设计的网站现在使用的是“邮件中心”。在这种设计中，当公司需要与客户通信时，它会发送一封包含类似以下内容的电子邮件：“您在邮件中心有一封邮件。请转到我们的网站，登录并单击‘邮件中心’链接以查看该邮件。”如果公司使用安全多用途 Internet 邮件扩展 (S/MIME) 协议对客户收到的所有电子邮件都进行签名以使用户能够验证其来源，则此公司值得表扬。如果电子邮件中不包括“请单击此链接”之类的内容，也值得表扬。用户应手动键入公司的 URL 以确保转到预期的站点。
通过采用邮件中心和邮件签名等措施，公司可建立一个与客户进行通信的受信任途径。客户在邮件工作流期间看到的所有内容都是经过验证的，而且公司不会采用不良的安全实践。

关于隐私
到目前为止，我已经通过本系列文章中的前两部分介绍了安全专业人员是如何在客观上对用户造成伤害的。维护安全是我们的职责。但制定的许多决策以及实施的许多解决方案都让用户感到困惑，会使他们做出错误的决策并给他们带来一种安全错觉。我们不应让这些矛盾的想法使用户变得无所适从。
正如我之前指出的，对于大多数用户而言，安全性只是保护密码和信用卡号码。他们需要的是有效而且可信赖的技术。不幸的是，他们必须做出抉择，而我们的职责就是确保他们清楚自己的行为。
在本系列文章的最后一部分中，我将介绍消费者可以使用的一些最重要技术为何没有实现预期的目的。我还会提出我的倡议。因此，敬请期待 2008 年 9 月的“安全观察”专栏。

Jesper M. Johansson 是研究安全软件的软件架构师，还是《TechNet 杂志》的特约编辑。他拥有管理信息系统博士学位，具有 20 多年安全方面的经验，并且是企业安全领域的 Microsoft 最有价值专家 (MVP)。他的最新著作是《Windows Server 2008 安全资源工具包》。


可持续计算 筛选漂绿
Dave Ohara

目录
数据的必要性
测量能源使用情况
功率因数
在生产中测量
Microsoft 企业工程中心
结束语
现在有相当多的产品和解决方案在宣传上都以环保、节能、高效为卖点。所有这些天花乱坠的广告宣传都会在市场上引发对相关产品是否确实环保的争论。即使在对各种产品的规格进行评估之后，IT 专业人员也很难（如果并非不可能）
确定在重点考虑环境影响时应使用哪种设备。在所有的演示中，好的节能效果始终都是亮点，您也会因此认定通过投资回报 (ROI) 就能更轻松地判定升级。毕竟，节省能源应该可以减少总体拥有成本 (TCO)。
由于各类公司都趋向于将其所有产品都冠以环保的头衔，并刻意打造环保解决方案，从而产生了“漂绿”这一概念，其含义是过分夸大环境方面的优势。那么，能源节省的真谛究竟为何？打个比方，它不能简单地界定为在您家中安装新型的节能灯泡。
随着人们对可持续 IT 工作的愈发关注及环保型 IT 设备市场的扩大，许多人和组织都转为部署节能型便携式计算机、台式机和服务器，并利用虚拟化减少能源消耗。但很少有组织会开展能源审计来确定其所购产品的真正价值。
虽然最好能在生产环境中积极进行评量，但成本可能相当高。如果您尚不能实施生产评量，可以通过先期执行能源审计而获得实效（在您的性能和评估实验室中完成审计）。（大部分公司都有一些实验室或小组负责在购买之前对设备进行测试和评估。）您可以在那里将能源性能作为一个新的测试条件，然后在做出购买决策时将这些结果考虑在内，而不是依赖于制造商所提供的数据。这样，随着您测试的进行，便创建了自己的设备能源消耗数据库。您也不会再为漂绿所左右，能挖掘出真正令自己受益的产品。
当然，我应该指出，如果您想要在真实工作环境中操作的精准数字，就需要监视您的生产环境。越早开始监视生产环境，您的组织受益越大，收效越好。这一过程对于您的长期成功非常关键。

数据的必要性
在理想情况下，应该有独立的测试来评估硬件设备在实际用户负荷下的能耗性能。但整个行业还处于开发和实施此类测试的初级阶段。那些现在可用的测试（如 SPEC Power 基准）仍处于其起步阶段。这些能源测试一旦得以完善，它们将会大展身手。但对于任何测试，制造商都将了解如何修改其设备以获得最佳的测试结果。
有经验的 IT 专业人员已经学会了质疑由测试实验室执行的测试。就像汽车公司确保其提供自己最好的汽车进行路面测试一样，IT 供应商也必将提供其最有效的设备配置来进行能源测试。
考虑使用虚拟化测试来比较一组超配置的服务器，其中没有执行任何服务器合并来显示虚拟化的优点。供应商忽视了其节能项目（如虚拟化）中可能存在的回弹效应等问题。从根本上来说，这是指能源效率在降低成本的同时导致需求增加，从而增加了能源消耗。当您看到某个解决方案（如虚拟化）被宣扬为节能的“万灵药”时，您应持怀疑态度。您必须确实了解所有工作是如何协作的以及随着时间的推移将产生哪些连锁反应。
那么，您如何找出适合您组织的途径呢？能对价格进行评估的顾问为数不少。但此方法有一些明显的不足之处。您确实想要将有效的专业知识传给您组织以外的人吗？您想依仗签长期合约的顾问并受制于他们的服务吗？
您可能使项目变得臃肿不堪，并且在确定您的环境可持续性策略时，参与的人员会过多。还应避免在您的环境中随便选取一个场所即开始评量。虽然主观意图没错，但方法没有任何意义，因为它只是一个随机操作。您需要找出消耗能源的真象以及您可以发挥影响的方面。

测量能源使用情况
您需要以一种新的方式来考虑什么在起作用。如果某项服务中断，IT 专业人员知道某个硬件何时不起作用。但是，就能源消耗而言，如何判定某个硬件在什么时候不能正常工作呢？这种测定可能会很难，因为许多组织都没有可建立其基准能源效率的数据。
您如何获取这些数字呢？一些人提出需要一个独揽能源大权的人。不过，这要求有人可以掌握公司组织的全面情况并且是能源问题的技术专家。一个简单易行的方法是将能源计量工具添加到性能实验室的现有功能中。
能源计量设备有许多。遗憾的是，此时却没有完全适合 IT 性能实验室的设备。在低端，您可以采用 Watts Up Pro。这是一台 USB 设备，提供了 120V 的内部功率测量。另一台设置是 Smart-Watt，一台可联网的功率消耗设备，其测量范围为 100-240V 和 15-30A。Smart-Watt 设备还配有温度和湿度传感器，用于测量环境因素。还有一些工业功率分析设备，例如 Extech Appliance Tester 380801 和 Fluke 345 Power Clamp。找到这些设备以满足实验室测试的需求应该不会出现什么问题。

功率因数
如果您首次测量功率，那么了解功率因数这一概念非常重要。交流电气系统的功率因数被定义为实际功率与视在功率的比值，其取值范围介于 0 和 1 之间。实际功率（瓦特）是电路的做功。视在功率 (VA) 是电路中的电流与电压之积。
您可能想知道这为什么很重要。看一下图 1。此图显示了 Smart Works 的能源监视设备，用于比较便携式计算机、灯泡和电容器的能源效率。灯泡的负载为 50 瓦特，视在功率为 50 VA，因此功率因数为 1.0。带有纯电容性负载的电容器的负载为 2 瓦特，视在功率为 193 VA，因此功率因数为 0.01。便携式计算机的使用功率是 22 瓦特，但视在功率读数为 48 VA，因此功率因数为 .47。便携式计算机的功率因数较低是因为设计的电源效率低下，而且很可能是制造成本目标的结果。
图 1 便携式计算机、灯泡和电容器的能源消耗（单击图像可查看大图）
由于能源效率如此重要，供应商现在正努力改进预期条件下电源的性能。如果您将现有设备的功率因数与新设备的功率因数进行比较，您会发现，如果能选用电源效率和功率因数更高的解决方案，可以减小功率损失。

在生产中测量
在性能实验室中测量结果是为预测生产环境的性能。在生产中测量能源消耗所面临的问题是测量所有设备所花费的成本。但有一个策略可以减少在生产中功率测量成本，即使用机柜电源插座 (PDU) 测量，然后合计多个设备读数。图 2 显示了从 PDU 获取的能源读数示例，一个机柜上有同一设备的多个部件。由于每台服务器的平均能源消耗是可以计算的，因此这种测量方式为您提供了生产能源消耗的数据。
图 2 使用机柜电源插座测量（单击图像可查看大图）
对设备各个部件进行测量时，应将能源信息集成到您的配置管理数据库中。如果这很难，您可以创建您自己的数据库，或者至少创建一个 Excel® 电子表格以列出设备及其能源消耗。随着设备的逐渐增多，您可以为其他设备填充估计值以创建计算整体功率值。请记住，与峰值状态相比，新型节能服务器在闲置时将消耗不到一半的功率负载。如果您的旧服务器还在运行过时的解决方案，那么这些旧服务器即使在闲置状态下也将消耗相当大的功率。如果在此方面有所改进，最容易提高利用率。
如果您要继续提高，接下来要计算您的数据中心中每个机架的功率。当您改变环境时还需了解功率和冷却能力。随着时间的推移，您将开始查看设备的功率需求，而不仅仅是该设备所需的空间。空间是一个简单的概念，它是静态的、可视的。IT 专业人员可以轻松讨论 1U、2U 和 4U 服务器，但开始讨论 200 瓦特服务器与 450 瓦特服务器时，您将发现这些 IT 专业人员的会谈就不甚流畅了。这是 IT 设备的新语言，在现在的数据中心十分常见。许多都拥有大量的空间，即使已经达到了其最大功率容量，也可以容纳更多的设备。

Microsoft 企业工程中心
Microsoft 企业工程中心 (EEC) 最近在其设备中添加了功率测量功能。EEC (microsoft.com/windowsserver/evaluation/eec/default.mspx) 位于华盛顿雷德蒙的 Microsoft 企业园区内，是最先进的试验场，能应对最复杂的计算环境。
EEC 在硬件和联网设备方面投入了 4000 万美元（请参见图 3），可以处理企业实际生产环境中最复杂的改造。该小组与许多一流的网络、存储和客户端/服务器解决方案提供商合作，将前沿技术与传统平台相结合。它的目标是确保每个测试准确反射客户的当前环境。在该设备中开发的最新服务是报告解决方案的能源消耗，为每瓦特性能提供基准。
图 3 EEC 实验室中的一排设备（单击图像可查看大图）
在过去的几年中，EEC 看到许多数据中心操作员都用尽了其设备的功率和冷却能力。最先进的设备通常具有更高的功率密度，这会给装备施加更大的压力。EEC 的员工最先了解到了升级电源和冷却基础结构所涉及的成本和时间。为了提高操作效率和成本效益，EEC 已经实现了按设备测量功率。
编写本文时，EEC 使用的一些工具和设备还没有面市。由于这是一个新的解决方案，因此 EEC 将与客户、供应商和 Microsoft 开发团队合作，继续开发更好的技术。EEC 与客户直接共享其到目前为止所开发的方法以获得早期反馈，从而使客户可以创建其自己的基准。
不要认为结果将显而易见。EEC 公布了它在 EEC 性能实验室中使用能源监视功能时所看到的一些有趣结果：
  1. 关闭设备并不一定会减少所预期的能源消耗（请参见图 4）。在一个涉及服务器硬件的案例中，EEC 发现有一台设备在关闭但仍接通电源时实际消耗了 100 瓦特。这让许多人都感到吃惊，EEC 对设置进行了多次检查。他们最终使用红外温度计来测量入口和出口温度，并证实该设备在关闭时实际上确实消耗了 100 瓦特。
  2. 软件对功率消耗可能有极其重要的影响。在相同的网络交换机上（具有相同的硬件和 BIOS 配置），运行不同的网络软件在功率消耗方面呈现出了 21% 的差异。高端解决方案启用了更多进程和功能（如安全性和监视工具），与其更简单的低端解决方案相比，功率消耗要大得多。
  3. 在虚拟化环境中，EEC 测量了功率消耗与 I/O 利用率和 CPU 利用率，以确定给定的硬件最大化其每瓦特性能的时间。EEC 发现片面追求 CPU 利用率可能会导致物理机上加载的虚拟机过多，实际上这会降低整体的每瓦特性能。
  4. 正如您所料，高密度设备的电源和冷却问题更多。部署高密度系统时，应尽可能早地咨询您的电源和冷却设备人员。如果您知道环境中的电力有限，这些设备可能是生产中其自身功率监视设备的首选。
  5. 双电源消耗的能量可能要比单电源大得多。
  6. 看来即使相同的硬件有相同的配置，功率消耗也会显著不同。所观察到的差异足以使 EEC 员工再次对硬件进行检查以确保它们的实际配置相同。
  7. 产品铭牌上的瓦特额定值不是实际消耗数字，而是电源的额定功率。
  8. 维护每台设备和子组件的能源消耗测试和结果的数据库对于保留知识和比较数据而言至关重要。
  9. 相等量 RAM 的不同配置所消耗的能量不同。DIMM 数量越少，通常消耗的能量也越少，例如，4 个 2GB DIMM 与 8 个 1GB DIMM。但有一些情况下，DIMM 数量越少消耗的能量却越多。
图 4 打开与关闭时的功能消耗比较（单击图像可查看大图）

结束语
通过在性能实验室中测量功率消耗，您可以使用实际负载的准确数据，在您自己的数据库中开始收集每台设备的能量消耗。部署这些解决方案时，您应审核闭环反馈结果以确定性能实验室测试的准确性。正如 EEC 通过运行其自己的测量测试所了解到的，您确实可以找到一些值得注意的细节，帮助您筛选出漂绿产品并发现真相。
这种在性能实验室进行的测量将会影响整体市场，帮助识别哪些产品确实最节能。随着时间的推移，制造商将会发现为其节能声明提供更加准确的数据是非常必要的。同样，IT 专业人员也会将每台设备消耗的瓦特数视为常用的采购条件。需要将其当成常规惯例，尤其是对于购买大量服务器的公司更应如此。不过，从现在开始，您可以率先将功率视为一项有价值的 IT 资源，对费用加以引导。
保持数据中心冷却
数据中心冷却设备为减少能源消耗提供了巨大的潜能。数据中心可能产生多少热量以及保持硬件冷却需要多少能量，这些数据是非常惊人的。但是如果您希望成功管理您的冷却设备，修复问题并开发更有效的冷却解决方案，您将需要一个温度监视解决方案。请考虑一下 Microsoft 数据中心使用的解决方案。
Microsoft 研究中心为数据中心构建了一个温度传感器网络，不但可以改善温度控制，而且还可以对各种冷却设备的改进进行评估。例如，一个 Microsoft 数据中心对用于改善冷热空气隔离的走廊末端空气幕进行了评估。安装空气幕后，一些服务器开始发出过热警报。操作工程师随之增大了冷却系统的气流，从而提供了更多的冷却空气。但令他们惊讶的是，有更多的服务器发出了过热警报。而且所有这些服务器都位于机架底部，而底部通常是架空地板冷却系统最冷的区域。
工程师通过传感器网络确认机架随着高度的增加温度降低，而机架底部是最热的部分。他们很快就发现了热空气来自于机架底部与地板之间的热过道，也就是柏努利原理的结果。他们通过将机架底部密封起来并减小气流速度轻松地解决了过热问题。
由于这恰恰是 Microsoft 企业工程中心在进行性能测试时所收集和分析的一类数据。因此，EEC 最近通知 Microsoft 研究中心他们已经做好了部署测试准备。在一天之内，将系统部署到 10 个机架中，仅花费一个小时就完成了安装。EEC 现在可以研究并更好地了解冷却问题及其与硬件性能的关系。
当然，仅仅监视本身并不是解决方案。真正的收益在于您能找出问题区域，可以修复、更改以及评估各种解决方案以了解它们是否能实现您所期望的结果。您当然不希望在新冷却解决方案意外导致机架过热时感到措手不及。

Dave Ohara 在技术方面已有 26 年的工作经验。他现在负责为多家公司实施环保计划。


领域备注 IMAP 拯救世界
R'ykandar Korra'ti

有时，一项解决方案是为处理新出现的小问题，但也可以解决原来遗留的大问题。以下就是一个例子。
去年冬天，我们的 Web 管理员购买了一台 MacBook。她以前一直只运行 Windows®，但现在她除了装有 OS X，还在虚拟机中安装了 Windows XP，用于同步其 Windows Mobile® 设备和其他一些小任务。
她需要从这两个操作系统访问她的所有邮件存档。但她不想在 Mac 端上运行 Entourage——要是那样的话问题就简单多了。她想运行 Mail.app（OS X 随附的电子邮件客户端）。顺便说一下，她的所有资料都存储在便携式计算机上，没有做镜像。我的工作：解决这个问题。
能够在任意位置读取存档文件代表的就是之前提到的小问题，因为我们一开始就提到，IMAP4 无处不在，Exchange Server、Microsoft® Office Outlook® 和 Mail 等都会用到它。IMAP4 是用于在瘦客户端处理服务器上消息存储的消息协议。在满足用户体验方面，IMAP4 可能略逊色于 Exchange，但它确实奏效（请参阅《TechNet 杂志》2006 年 3-4 月刊中的“IMAP4 的工作原理”，网址为 technet.microsoft.com/magazine/cc161016）。
因此，更改了一些设置以使 IMAP4 over SSL 可以联机访问、将其所有本地文件夹复制到服务器上，然后执行 ping 命令！这样，她便可以在所有客户端上访问邮件并使自己的 Windows Mobile 设备保持更新。问题得到了解决。
但针对潜在难题提出一个简单的解决方案就好比是得到了一把新台锯。您突然有种跃跃欲试的冲动，想对原来已成型的东西来翻改造。
我们的小型 ISP 运行 Windows、OS X、Mac OS、Linux，甚至还包含一个古老的 AmigaOS 系统。很久之前，我们在该 Amiga 上托管了 Usenet 新闻和 UUCP 邮件。创建的存档以 RFC-733/AmigaUUCP 格式存储。我们还有 Microsoft Mail 存档（.mmf 格式）和一些年代久远的 UNIX 邮件存档（.mbox 格式）。它们都是让人避之不及的难题，现在都等着我们来解决。
这一场景引出了我们的第二条准则，一句危险黑客的座右铭：切勿删除你不能替换的项目。
我们先来解决 Microsoft Mail 存档。Outlook 有时无法导入 .mmf 文件。但是，由于我们过去一直在升级客户端，所以至少为每种老产品保留了一份许可证，只是您从不知道而已。因此，我们保留的许可证见证着 Microsoft Corporation 的历史足迹。您需要 MS-DOS®？OS/2 1.31？Microsoft Mail？还是 Office 95？当然可以！要英语的，还是法语的？
Outlook 2000 能导入 .mmf，但它的 IMAP 支持是陌生的，并且偶尔会丢弃标头数据。还有，它不能同时与 IMAP4 和 Exchange 服务器对话。它还不是一个良好的解决方案。使用 Outlook 2000 导入 .mmf 文件，升级到我们保存的 Outlook 2003 许可证，然后花些时间拖放：15 年之久的存档就能联机并可在任意位置查看。对 .mbox 采用类似方法，在 Linux 机器上放置一个与 mbox 兼容的 IMAP 服务器，将 .mbox 格式的存档放入其工作目录中。然后使用 Outlook IMAP 支持连接文件夹并将其复制到选择的生产服务器上。
Amiga 存档则需要编写一小段 C 代码将 RFC-733 标头转换为 RFC-822 格式，摆脱 SysV 样式的旧消息分隔项并从其专用环境中检索出特殊的 From: 行数据。这就是因问题存在时间过长而付出的开销。但是问题得以解决后，AmigaUUCP 格式就成为 .mbox 格式。放入相同的工作目录后，Outlook IMAP4 便可完整地取得邮件，就象新的一样。其中的附件也都完好无损。
现在，我们让 1990 年的存档以标准格式重新上线，并且还能搜寻更多的存档，就是因为我们能做到这一点。够强吧？

R'ykandar Korra'ti 是一家小型合作 ISP 的邮局主管，同她的合作伙伴 Anna 一起住在西雅图附近。她之前在 Microsoft 担任产品邮寄工作，从她不再痴迷于曼陀林歌词的那时起便转向了撰写技术性文章。期刊预订代理商可以通过 darako@murkworks.net 与她联系。


Windows 机密 昔日的王者
Raymond Chen

我的一名同事从积满灰尘的储物柜中翻出了一台 Alpha AXP 计算机。在引导系统时，他发现这台计算机运行的竟然是 2000 年年初的 64 位版本 Windows®。这怎么可能呢？
我的办公室恰巧也有一台这样的计算机。在它的辉煌时期，这款计算机可谓风靡一时。它的体积约有小型冰箱大小，发出的噪音与真空吸尘器差不多。它包括四个 — 让我来数一下，对，四个！— Alpha AXP 处理器，每个处理器的频率都达到了令人难以置信的 400 MHz。它拥有 1 GB 的 RAM 和 13 GB 的硬盘空间，且条带化配置了超过一打的快速 SCSI 驱动器。现在听起来可能微不足道，但在 20 世纪 90 年代，这些 Alpha AXP 计算机是整个街区的焦点，它会使您成为午餐桌上最受瞩目的人。
在 1999 年，当 Compaq 宣布 Alpha AXP 不再支持 Windows 时，许多 Alpha AXP 系统随即在公务使用领域放弃了 Microsoft。但是，其中的一些计算机却被用于各种非公务场合。当时我把我的 Alpha AXP 系统对整个 Windows 源代码进行了索引编制。您可以想象，对一个程序员来说，能够在几秒钟内找出某个函数的所有调用者或者准确定位在调试跟踪中显示的某个函数或对话框的源代码该是多么方便。
但即使是对这样一个为 Windows 源代码编制索引的简单任务，Alpha AXP 很快也由于 x86 计算机的出现而变得相形见绌。这些计算机不但更快更便宜，而且还提供更多的硬盘空间、具有更多的内存。因此，我的计算机很快也沦落到了被遗忘之列。人们都认为对 Alpha AXP 支持的结束也意味着这些计算机走上了末路，但之后出现的机遇使其又重新焕发了活力，在退出历史舞台之前为下一代产品的问世做出了贡献。
64 位 Windows 项目已在顺利进行中，64 位处理器正在考虑当中，只有 Alpha AXP 具有实际的产品。Intel Itanium 仍在开发中，只能在模拟器中运行，而 AMD64 体系结构甚至还没有被发明出来。结果，64 位 Windows 最初是在 Alpha AXP 上开发的。
当 Compaq 宣布 Alpha AXP 不再支持 Windows 时，所有这些之前被用于 32 位 Windows 2000 开发和测试的 Alpha AXP 计算机即被赋予了新的秘密使命，开始用作 64 位操作系统的测试机器（虽然它绝不会以该形式发布）。Alpha AXP 只是一个概念证明平台。
Alpha AXP 机器非常适合该角色，它为 64 位 Windows 团队提供了可以操作的真实硬件，而不必在 Itanium 模拟器上运行该操作系统。（您可以想象那样速度会有多慢。）当然，Alpha AXP 并非最终的目标硬件，但它却非常有帮助。当实际的 Itanium CPU 开始出现时，Alpha AXP 组成的小环境随即消失，它们被再次堆放在积满灰尘的储物柜中。
我在 Microsoft 存档部门工作的朋友把我以前值得信赖的 Alpha AXP 从满是灰尘的储物柜中拿了出来并拍摄了这张照片，和它摆放在一起的还有在开发时它曾立过汗马功劳的其中一种产品：64 位版本的 Microsoft Windows Server® 2003。没错，那就是当初堆积的灰尘。

Raymond Chen 的网站 The Old New Thing 及同名书籍 (Addison-Wesley, 2007) 讨论了 Windows 历史和 Win32 编程。他不希望它们被锁在布满灰尘的储物柜中。