组策略

优化组策略性能

Darren Mar-Elia

 

概览:

  • 整体化与功能化 GPO
  • 如何处理组策略条目
  • 当 GP 改变时会发生什么情况

我经常会被问及“从性能方面考虑,是配置少量较大的 GPO 好还是配置大量较小的 GPO 好”这一问题,本文将集中讨论此问题以及其他与组策略设计和性能相关的问题。同时还会涉及大量常见问题。

我可以先告诉你答案:“视情况而定。”虽然这个答案可能有点含糊其词,但我的目标是阐明组策略的处理机制,这样无论您是正准备开始配置组策略,还是准备优化众多现有的 GPO 环境,都可以对组策略设计做出正确的决策。

整体化与功能化 GPO

让我们首先介绍一下实现 GPO 的不同方法。术语“整体化”和“功能化”是针对您的设计方式而言的。整体化 GPO 包含许多不同方面的设置。例如,整体化 GPO 可能包含来自“管理模板”、“Internet Explorer 维护”以及“软件安装策略”(所有这些都在单个的 GPO 中)的设置。相反,功能化 GPO 通常只包含一个方面。例如,功能化 GPO 可能只进行“软件安装”或只进行强制的“安全”设置。我甚至还见过有的功能化 GPO 只包含一项策略设置!当然这可能只是极端情况。图 1 显示了各种方法的部分优点和缺点。

Figure 1 比较整体化与功能化 GPO

问题 整体化 GPO 功能化 GPO
委派/隔离 困难,因为各个 GPO 可能包含来自多个区域的设置,而您只能在 GPO 级别而不是设置级别进行委派。 简单,因为每个 GPO 只包含单一的策略区域,您可以将软件安装 GPO 委派给部署管理员,而将安全 GPO 委派给安全官员,诸如此类。
可管理性和复杂性 管理起来可能会比较简单容易,因为每个 GPO 都在单独的位置中包含所有设置。 可能会比较困难,因为 GPO 越多则意味着需要查找更多的位置来跟踪问题,而且在确定给定用户或计算机的策略结果集时会非常复杂。
性能 可能会较慢,因为对于给定的客户端侧扩展而言,如果一个 GPO 发生变化,则所有扩展都需要针对范围内的所有 GPO 加以运行。 取决于使用的 GPO 数量以及更改频率。在动态环境中,性能可能会稍好于整体化 GPO。
     

您可以可看到,对于“哪种方法(整体化还是功能化)在所有情况下都最适合”这样的问题并没有绝对肯定的回答。在您的环境中,可能两者都需要。例如,在为整个域创建安全策略时,可能功能化方法更适合一些。在一个单独的 GPO 中仅包含安全设置可便于将该 GPO 的控制权委派给安全管理员,而其他人均无法对其执行操作。同样道理,如果将 GP 管理委派给 OU 管理员,然后为每个 OU 建立一个整体化 GPO,这将为这些管理员提供一个单一位置,使其能够在其中管理其所有策略设置。这可以降低其复杂性,并使您能够调节为给定 OU 的用户和计算机所创建的 GPO 的数量。

这些高级别设计决策将如何影响组策略处理的性能,如何才能做出明智的 GP 设计决策以最大程度地减小对性能产生的影响?要想最大程度地提高组策略基础结构的性能,首先要了解组策略处理过程的工作原理。

了解组策略处理过程

组策略处理是一组复杂的交互过程,其中涉及 Windows® 和 Active Directory® 基础结构的许多方面。从较高的层次来看,组策略处理过程分为两个部分。第一部分称为“核心”或“组策略基础结构”处理过程。在这一阶段,Windows 组策略客户端向其最近的域控制器进行查询以确定 DC 的链接速度是多少、在 Active Directory 层次结构中处于什么位置(即客户端是哪个站点、域和 OU 的成员),以及哪些 GPO 适用于该计算机或当前登录的用户。(特别要注意,在此上下文环境中,客户端可以是加入到 Active Directory 域的服务器或工作站。)GPO 列表创建完毕后,即开始执行下一阶段 — 客户端扩展 (CSE) 处理过程。在 CSE 阶段,各个注册的 CSE 都会对那些已在其区域内实现了设置的 GPO 的列表进行处理。例如,注册表或管理模板 CSE 始终会先运行并处理应用到给定计算机或用户的所有 GPO,以及已在内部实现了注册策略的 GPO。

下面的列表详细说明了组策略处理循环的执行步骤,包括客户端和域控制器之间的网络交互。务必要记住,组策略既应用到计算机也应用到用户。因此,对于每次策略处理(例如在组策略的后台刷新期间),在给定系统的计算机和当前登录用户帐户中都会重复执行下面列举的循环 I,因为它们所应用的策略集可能互不相同。当出现这种情况时,Windows 实际上为计算机和用户都会执行此处理循环,而各个循环都在组策略引擎进程内的不同线程中运行。(Windows 2000、Windows XP 和 Windows Server® 2003 的 Winlogon 进程,以及 Windows Vista® 和 Windows Server 2008 中的“组策略客户端”服务。)

GP 的处理过程分为 6 个步骤:

  1. 客户端对其站点内的域控制器执行“Internet 控制消息协议”(ICMP) 慢速链接检测以确定链接速度。在 Windows Vista 中,已不再使用 ICMP 进行慢速链接检测,取而代之的是“网络位置感知”(NLA) 服务。
  2. 客户端从其本地注册表中读取 CSE 状态信息,以确定哪些 GPO 是最后处理的。
  3. 客户端使用 LDAP 在它于 Active Directory 层次结构中所处的位置内(首先在 OU 级别(包括所有嵌套的 OU),然后在域中,最后在 Active Directory 站点级别)搜索各个容器对象在 Active Directory 中的 gpLink 属性。然后,根据这一搜索结果,它将建立一个必须进行处理评估的 GPO 的列表。
  4. 每个 GPO 将随后在 Active Directory 中进行搜索以确定该客户端(用户或计算机)是否具有必需的处理权限。同时还将评估其版本号、在 SYSVOL 中 GPO 的“组策略模板”(GPT) 部分的路径以及在该 GPO 中实现了哪些 CSE。
  5. 然后,客户端使用“服务器消息块”(SMB) 协议读取 GPT 的内容,并从 gpt.ini 文件中获取 GPO 的版本号。“组策略容器”(GPC) 和 GPT 中的版本号是用来确定自上个处理循环以来 GPO 是否被更改过的一个依据。
  6. 各个 CSE 都按照在 HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions 中的注册顺序运行,并且如果 GPO 自上个处理循环以来曾被更改过(在核心处理过程期间确定),则会对实现该 CSE 的 GPO 进行处理。各个 CSE 还将在每次刷新期间把“用户策略结果集”(RSOP) 数据记录到“Windows 管理规范”(WMI) 中。

让我们仔细分析一下此过程并看一看它如何影响性能。首先要明确的是前台和后台处理有所不同。前台处理过程发生在计算机的系统重新启动期间以及用户的用户登录期间。默认情况下,工作站和成员服务器的后台刷新频率为 90 分钟加上 30 分钟以内的一个随机值。域控制器上的后台刷新频率默认为 5 分钟。在 Windows Vista 中,您还可以使用基于 NLA 的刷新,它们实质上是属于后台刷新事件,如果由于对域控制器的访问权限不足而导致组策略处理过程失败(例如当后台刷新间隔到期时客户端刚好离线),则会触发这些事件。这些区别为什么非常重要?主要是因为某些 CSE(例如“软件安装”以及“文件夹重定向”CSE)在后台刷新期间不会运行。同样,登录/注销或启动/关机脚本在后台刷新期间也不会运行。

类似地,在此过程的步骤 1 中,我曾提到过慢速链接检测过程。在 Windows Vista 之前的系统中,此过程必须通过客户端使用 ICMP 对域控制器执行 ping 操作来确定其可用性和链接速度。如果计算得出的链接速度低于某个阈值(默认是 500Kb/s),则认为链接过慢,这时,某些 CSE(例如“软件安装”、“文件夹重定向”以及“Internet Explorer 维护”)将不会运行。所有这些条件都可能会对性能以及预期策略交付产生影响。

对性能会产生很大影响的策略处理循环或许是确定应用到计算机或用户的 GPO 是否已发生更改的逻辑。组策略引擎有一个内置的优化原则,即如果自上次 GP 被处理以来计算机或用户未发生任何变化,则不进行处理。这显然会对客户端处理策略所用的时间产生巨大的影响,特别是当您的 GP 环境处于近乎静态的情况下时。让我们来进一步了解一下发生改变的原因。

组策略何时发生改变

那么到底是什么原因导致组策略处理过程发生改变呢?原因有多种,但最明显的是如果对 GPO 进行了改动,则处理该 GPO 的客户端会检测到此改变并因此将重新处理该 GPO。客户端如何知道 GPO 已更改?它是根据 GPO 的版本号和客户端内部的版本号计算得到的。

GPO 由两部分组成:存储在 Active Directory 中的 GPC(在各个域的 CN=Policies、CN=System 容器内),以及存储在 SYSVOL 中 "Policies" 文件夹内的 GPT。GPO 的各个部分都包含一个版本号。对于 GPC,此版本号存储在 GPC 对象的 versionNumber 属性中。对于 GPT,它存储在给定 GPT 的根目录下的 gpt.ini 文件中。客户端还会在其注册表内保留已处理的 GPO 的版本号记录(包括对每台计算机和每位用户的记录)。对于各客户端的计算机,此版本信息位于 HKLM\Software\Microsoft\Windows\Currentversion\Group Policy\History 中;对于用户,此信息位于 HKLM\Software\Microsoft\Windows\Currentversion\Group Policy\<用户的 SID> 中。

当组策略处理过程开始时,其中一部分工作是检查计算机或用户所属的所有 GPO 的版本号,然后将其与注册表中找到的在上次循环中处理过的版本号进行比较。如果当前 GPO 的版本号有任何不同(注意,只要有不同之处即可,无论是差别很大还是只有细微差别),则在当前处理循环中都会处理这些 GPO。否则将不会对其进行处理,除非满足其他某个更改条件。这里所说的其他更改条件包括:

  • 应用到用户或计算机的 GPO 列表发生改变(添加或删除了 GPO)
  • 用户或计算机的安全组成员身份发生改变
  • 关联到 GPO 的 WMI 筛选器发生改变(添加或删除了 WMI 筛选器)

如果满足上述任一更改条件,客户端都将在该循环中重新处理策略。但此过程中有些细微差别需要引起注意,因为它们可能对性能产生重大影响。对于给定的 CSE,如果 10 个 GPO 中有 1 个发生了改变,则必须对该 CSE 中的所有 GPO 进行处理。请记住,过程处理是以各个 CSE 为基础进行的。但是,CSE 必须以控制流程时使用的优先顺序来处理策略(首先是本地 GPO,其次是站点链接的 GPO,接下来是域链接的 GPO,然后是 OU 链接的 GPO)。根据这一要求,我们假定对某个用户应用 10 个 GPO,其中每个都链接到 Active Directory 层次结构的不同级别。此外还假定这 10 个 GPO 每个都实现了某些管理模板策略设置。现在,管理员将介入并更改某个链接到域的 GPO — 添加一个新的管理模板策略设置。随后计算机或用户开始处理策略并发现所更改的 GPO 的版本号大于上次处理的版本号,因此需要再次处理该 GPO。但是,为了维持 GP 处理过程的优先顺序,必须先处理应用到所有 GPO 的全部管理模板设置。所以说,对一个 GPO 的轻微改动就可能会对该客户端造成重大的性能影响。

比较整体化 GPO 与功能化 GPO 的性能

到目前为止我们已经探讨了处理循环以及对组策略环境的更改将对处理过程产生哪些影响,接下来让我们回过头来看一看对整体化与功能化 GPO 性能比较的讨论,以及这两种方法如何影响性能。

鉴于组策略的版本检查方式,整体化 GPO 可能会面临潜在的性能问题。虽然导致这种情况出现的原因错综复杂,但它们都与这一事实有关:即在组策略处理过程中,并没有对各个 CSE 进行版本检查。让我们假定某个用户有三个适用的 GPO。每个 GPO 都是整体化 GPO,其中实现了多个策略区域。例如,假定各个 GPO 都实现了管理模板策略、软件安装策略以及文件夹重定向策略。现在,我们假定管理员对其中一个 GPO 中的管理模板策略进行了更改。这次更改使版本号增加。随后用户介入并处理组策略。管理员模板 CSE 启动并检查到其中一个 GPO 发生了变化,这样它将再次处理这三个 GPO。

当“软件安装”和“文件夹重定向”CSE 运行时,它们也对 GPO 版本号进行了检查并注意到其中一个 GPO 已变为新版本。但由于该版本号无法告诉它们在该 GPO 中哪个策略区域发生了改变,所以为了以防万一,它们不得不重新处理全部三个 GPO。这样做的结果就使得在整体化 GPO 实现中,对其中一个策略区域进行更改可能会导致不得不在其他区域中执行处理过程。

当然,在软件安装或文件夹重定向策略中,这些 CSE 实际上可能并不执行任何工作,例如,如果某个应用程序已经安装完毕,则不会再次进行安装。但我们要指出的是这种行为可能会发生在任何 CSE 中,因此在设计整体化 GPO 时,必须将这一点考虑在内。如果某个策略区域经常发生变化,则可能需要考虑将实现该策略区域的 GPO 与其他策略区域分隔开。

从功能化 GPO 的角度看,这更侧重于性能方面的考虑。如果每个用户或计算机有多个 GPO(因为对给定的一组策略设置,功能化方法通常包含多个 GPO),则意味着在组策略处理过程的核心阶段,组策略引擎需要花费更多的时间来枚举这些 GPO。但是,正如我们将在下一节中看到的一样,这种方法可能并不会对性能造成太大的影响。

度量组策略性能

最后,为了更准确地确定组策略基础结构的性能,您需要能够度量组策略在真实环境中的性能。建模或预测组策略性能几乎是不可能的,因为大量的因素都可能会对既定处理循环产生影响。因此,根据经验进行度量是确定 GP 处理性能是否存在问题的最佳方式。导致性能低下的原因是什么?只要组策略处理过程影响到用户的系统体验,即可视为性能低下。可能每个组织的观点不尽相同,但关键是要知道确实存在这种问题。

那么,如何来度量给定组策略处理循环的持续时间呢?同样,这个问题也不是三言两语就能回答的。如果您运行的是 Windows Vista 或 Windows Server 2008,那么您可以充分利用新的“事件查看器工作日志”。事件查看器中的组策略工作日志位于 Applications and Services Logs\Microsoft\Windows\Group Policy\Operational 下,它提供了组策略处理循环中各个步骤的详细说明,包括各个处理阶段所用的时间(请参阅图 2)。

图 2 显示策略处理时间的组策略操作日志事件

图 2** 显示策略处理时间的组策略操作日志事件 **(单击该图像获得较大视图)

但是,如果您不在 Windows Vista 或 Windows Server 2008 环境中工作,那么度量策略处理时间的机制将不会如此直接。这时您可以选择启用 verbose userenv logging(请参阅 Microsoft 支持文章 support.microsoft.com/kb/221833)并查看该文件内针对给定处理循环的时间戳,或使用客户端注册表中保存的值来指出策略处理的起止时间。对于计算机,这些值存储在以下位置:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\
Group Policy\State\Machine\Extension-List\
{00000000-0000-0000-0000-000000000000}

对于用户,这些值存储在以下位置:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\
Group Policy\State\<SID of User>\Extension-List\
{00000000-0000-0000-0000-000000000000}

这些值以 FILETIME 格式存储,必须转换为正常的日期和时间。您也可以使用我编写的免费 GPTime.exe 实用工具(在 gpoguy.com/tools.htm#GP_Time_Utility 中提供)得到相同的信息。

如果您没有 Windows Vista 或 Windows Server 2008 环境,但却可以访问 userenv 日志,那么您仍可以获得有关每个策略处理循环需要花费多长时间的有价值信息。例如,图 3 是 userenv 日志的一个片断,它显示了组策略处理过程核心阶段的部分信息。

图 3 userenv 日志的片断

图 3** userenv 日志的片断 **(单击该图像获得较大视图)

请注意,日志文件的每一行都包括一个时间戳。组策略处理循环核心部分的开头内容类似于 "ProcessGPOs:Starting user Group Policy (Background) processing ..."处理循环的 CSE 部分的开头内容类似于"ProcessGPOs:Processing extension Registry."您可以使用此日志和其中的时间戳来确定策略循环的各个部分所花费的时间。

有关性能问题的一般意见

在详细查看 userenv 日志文件后,您会发现一些模式,尽管无法预计策略处理过程需要花费的时间,但您可以就给定处理循环中时间的花费环节提供一些一般性意见。例如,在策略处理事件期间,当进行策略更改并因此导致 CSE 需要做一些额外工作时,花费在 GP 处理过程核心部分的时间通常要远少于花费在 CSE 部分的时间。

对于大多数策略区域来说情况均是如此,因为大多数 CSE 都需要执行比处理过程的核心部分运行起来更耗时的任务,其中最耗时的操作是查询 Active Directory 和 SYSVOL。例如,核心处理过程所花费的时间与运行 Microsoft® Office 安装程序的“软件安装”CSE 所花费的时间就不具有可比性。但是,对于那些自上个循环以来未发生任何变化的正常后台刷新,处理循环的核心部分与 CSE 部分所用的时间基本相同。但注册表策略处理是一个例外,除非给定用户或计算机有成百上千条注册表策略设置,否则其实际处理速度会相当快。

此外,禁用计算机端或用户端未使用的 GPO 对策略处理性能几乎没有影响。如果某个策略端从未使用过,则唯一的开销就是查询 Active Directory 对此进行确认,并且还必须执行一个查询来查看禁用的选项,该查询与确定是否已为该 GPO 端实现 CSE 时使用的查询相同。禁用一端后所产生的效果可以忽略不计。

优化 GP 性能的设计建议

至此我们已经讨论了组策略处理过程性能的许多方面,以下将给出一些对性能有直接影响的设计建议。按四个要点对这些建议进行了总结。

  1. 如果经常要对 GPO 进行更改,则请记住前面所讲的效果(对一个 CSE 所做的更改可能会影响所有 CSE 的处理过程)。因此,以注册表策略为例,如果打算经常对其进行更改的话,最好将注册表策略加入功能化 GPO(只处理注册表策略的 GPO),以便在进行更改时与其他 CSE 处理过程隔离开。
  2. 在考虑究竟多少 GPO 才算是数量过多时,要认识到策略处理过程只发生在更改期间,某些“开销大”的 CSE(例如软件安装、文件夹重定向、处理大量注册表策略或对大型文件或注册表目录设置许可权限)会占用大部分时间。在核心处理过程期间向 Active Directory 查询 GPO 列表所花费的时间在处理循环中通常只占最少的部分。因此,与只应用 5 个 GPO 但却定期运行开销很大的 CSE 所花费的时间相比,对给定用户应用 30 个 GPO 但只偶尔进行少量的注册表策略更改所花费的时间可能要少,因为对于前者而言 GPO 会频繁发生变化。
  3. 应避免采取会明显降低组策略处理性能的行为。例如,您可以设置策略来强制执行 CSE 过程,即使 GPO 尚未发生改变(在 Computer Configuration\Administrative Templates\System\Group Policy 下设置)。但如果这样做,在每个循环期间策略处理过程所花费的时间都会变长。
  4. 请记住,要根据情况决定是否禁用 Windows XP 和 Windows Vista 中的“快速登录优化”(通过在 Computer Configuration\Administrative Templates\System\Logon\Always wait for the network at computer startup and user logon 中启用该策略来设置)。启用此策略后,前台处理过程将从异步切换到同步。这意味着计算机和用户策略必须在用户获得计算机和桌面的控制权之前运行完毕。但是这样也有好处,因为它可以解决“软件安装”和“文件夹重定向”策略需要重新启动或登录两次或更多次才能生效的问题。

总结

尽管组策略处理性能不算是精密科学,但您也可以在设计过程中引入一些深入的技术来缓解性能问题。

了解处理循环的工作方式以及时间的花费环节有助于您对性能问题进行跟踪。使用 Windows Vista 或 Windows Server 2008 的工作日志(对于 Windows 的早期版本,需使用 userenv 日志)获取有关处理循环的指导性信息。要记住 CSE 处理过程的特点以及被 CSE 视为策略更改的条件。还要记住,在变化莫测的动态环境中,功能化 GPO 可能要比整体化 GPO 更适用。但最根本之处在于组策略是一种旨在帮助您更好地管理 Windows 环境的技术。非常重要的一点是要根据您的业务需求来确定组策略设计,而不是反其道而行之。记住本文所讨论的一些性能行为可帮助您实现该目标。

Darren Mar-Elia是 Microsoft 组策略 MVP,他创建了流行的组策略站点 — www.gpoguy.com,并且参与撰写了《Microsoft Windows Group Policy Guide》(Microsoft Windows 组策略指南)(Microsoft Press,2005)。他还是 SDM Software, Inc. 的 CTO 和创始人。您可以通过发送电子邮件到 Darren@gpoguy.com 与他联系。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.