GPMC 脚本编写

自动完成 GPO 管理任务

学习如何利用组策略管理控制台 (GPMC) 中所包含的脚本接口自动完成许多常见的 GPO 管理任务。本文来自 2003 年 8 月份的Windows & .NET Magazine

*
本页内容
简介简介
GPMC 脚本入门GPMC 脚本入门
检索 GPO 的权限检索 GPO 的权限
获取 RsoP 报告获取 RsoP 报告
GPMC 带来新的可能GPMC 带来新的可能

简介

四月份,Microsoft 发布了组策略管理控制台 (GPMC),它提供了一个基于 Microsoft 管理控制台 (MMC) 的 UI,从而简化了对 Windows Server 2003 和 Windows 2000 组策略的管理。与 Windows 2000 的本地工具相比,GPMC 代表了组策略对象 (GPO) 管理功能的一大进步。使用本地工具编写 GPO 管理脚本非常困难。但是,GPMC 包含了一组脚本接口,用于自动处理许多常见的 GPO 管理任务。使用这些脚本接口,您能够管理组策略环境,包括生成 GPO 设置报告、创建和复制 GPO 以及查找未链接的 GPO。Microsoft 提供了一些 GPMC 脚本,涵盖了许多常见的脚本撰写任务。您还可以创建自己的脚本来执行自定义的 GPO 管理任务。

虽然您可以管理基于 Windows 2000 域的组策略,但是 GPMC 只能在 Windows 2003 和 Windows XP Professional 计算机上运行。(有关 GPMC 的要求和特性的更多信息,请参见 "Windows Server 2003's Group Policy Management Console",该文于 2003 年 7 月在http://www.winnetmag.com发布,InstantDoc ID 39190。)您可以从 Microsoft 下载中心 (http://www.microsoft.com/downloads/details.aspx?FamilyId=0A6D4C24-8CBD-4B35-9272-DD3CBFC81887&displaylang=en) 下载 GPMC。当您安装 GPMC 时,系统会创建一个名为 Scripts 的文件夹,其中包含所有预先编写的 GPMC 脚本。在 Windows 2003 或 XP 客户端上,此文件夹位于 %programfiles%\gpmc 目录中。主管理脚本的扩展名是 .wsf,这是与 Windows 脚本宿主 (WSH) 相关联的文件格式之一。带有 .wsf 扩展名的脚本是 XML 格式的文件,它能够调用其他的以 VBScript 或 JScript 编写的脚本,这意味着一个脚本能够同时利用 VBScript 和 JScript 脚本引擎。在本文中,我使用 VBScript 编写不依赖于 .wsf 文件的脚本。

GPMC 接口是在 gpmgmt.dll 中实现的,它位于 %programfiles%\gpmc 目录中。Microsoft 提供这些接口的目的是使 GPMC 功能以及管理 GPO 自动化。因此,您不但可以使用这些接口编写 GPMC 操作脚本(例如,为 GPO 移植创建映射表),而且可以用它们查询和修改 GPO。但是,GPMC 接口不允许您读取或配置 GPO 内的策略设置。例如,您不能创建一个脚本来启用一个 GPO 内的 Remove Run from Start Menu 管理模板策略。这一限制很不幸;虽然如此,GPMC 接口仍然提供了迄今为止最高的自动化程度。让我们看看如何开始撰写 GPMC 脚本以及如何使用 GPMC 对象执行各种管理任务,例如检索一个 GPO 的权限和获取策略的结果集 (RSoP) 报告。

返回页首返回页首

GPMC 脚本入门

学习编写 GPMC 脚本相当简单。您编写的所有 GPMC 脚本都遵循相同的基本步骤。就像您在 WSH 环境中使用的大部分新对象一样,您首先需要创建您想要使用的对象的实例或称为实例化。在所有的 GPMC 脚本中,您需要实例化的第一个对象是 GPM 对象。此对象是 GPMC 对象模型中的根对象。您需要利用 GPM 对象来访问其他的 GPMC 接口,然后利用后者访问更多的功能。例如,您需要利用 GPM 对象来访问 IGPMDomain 接口,该接口允许您创建对 Active Directory (AD) 域的引用。在拥有了对 AD 域的引用之后,您可以调用 IGPMDomain 的 GetGPO 方法来访问 IGPMGPO 接口并创建对您要管理的特定 GPO 的引用。此时,IGPMGPO 接口包含管理该 GPO 的方法和属性。您可以在名为 gpmc.chm 的帮助文件中了解关于 GPMC 对象模型的更多信息,该文件位于 Scripts 文件夹。您还可以在 Microsoft Developer Network (MSDN) 的组策略管理控制台参考页面http://msdn.microsoft.com/library/en-us/gpmc/gpmc/group_policy_management_console_reference.asp了解此对象模型。

另一个您可能会用到的接口是 IGPMConstants,它是 GPMC 脚本撰写的一个特殊接口。此接口提供一组属性,表示与 GPO 相关的常量,在 GPMC 脚本中常常会用到这些常量。例如,假设您需要设置权限来控制谁能够编辑一个 GPO。您可以使用一套复杂的文件系统和 AD ACL 来表示“编辑”权限,但这个方法需要进行大量的编码工作。因此,Microsoft 提供了 IGPMConstants 接口为您完成这个工作。您只需调用 IGPMConstants 接口的 PermGPOEdit 属性来表示合适的权限。要访问 IGPMConstants 接口,您可以使用 GPM 对象的 GetConstants 方法。在使用 GetConstants 方法获取了对 GPMConstants 对象的引用之后,您就可以在您的脚本中使用任何 GPMConstants 属性。

列表 1 显示了用于创建 GPM 和 GPMConstants 对象的代码。让我们通过两个示例脚本 GetGPOPerms.vbs 和 RSoPLogging.vbs 来了解如何利用此代码。坦白说,这些脚本不是最基础的。我不想重复 Microsoft 提供的 GPMC 脚本。

列表 1 创建 GPM 和 GPMConstants 对象的代码

BEGIN COMMENT
' Code that creates the GPM object.
END COMMENT
Set GPMC = CreateObject("GPMgmt.GPM")
BEGIN COMMENT
' Code that creates the GPMConstants object.
END COMMENT
Set Constants = GPMC.GetConstants()
返回页首返回页首

检索 GPO 的权限

列表 2 中的脚本 GetGPOPerms.vbs 演示了如何使用几个 GPMC 对象来列出在一个测试域中某个 GPO 的权限。GetGPOPerms.vbs 从实例化 GPM 和 GPMConstants 对象开始。然后,脚本访问 IGPMDomain,这是一个有用的接口,它允许您检索有关域的信息并在其中管理 GPO。要访问 IGPMDomain,您可以使用 GPM 对象的 GetDomain 方法,它返回一个 GPMDomain 对象。正如列表 2 中的 标注 A 所显示的,GetDomain 方法采用三个参数。第一个参数是存储您要管理的 GPO 的域的名称。此域名必须是该域的 DNS 名称(例如,mycompany.net)。正如标注 A 所示,您可以在脚本中对此参数的值进行硬编码。另一个方法是让脚本的使用者在启动此脚本时从命令行输入域名。

第二个参数让您指定要使用哪个域控制器 (DC) 来连接域。空字符串 ("") 表示没有首选 DC,这意味着 GetDomain 方法将会使用 PDC 模拟器。第三个参数用于指定您希望使用哪个选项来查找用于连接的 DC。您有三个选项:GPM_USE_ANYDC(使用任何可用的 DC)、GPM_USE_PDC(使用 PDC 模拟器 DC)或 GPM_DONOTUSE_W2KDC(使用运行 Windows 2003 的 DC)。如标注 A 所示,GetGPOPerms.vbs 使用 GPMConstants 对象的 UseAnyDC 属性来指定 GPM_USE_ANYDC 选项。

在连接到域之后,真正的乐趣才刚刚开始。如同列表 2 中的标注 B 所示,使用 GPMDomain 对象的 GetGPO 方法来检索 GPMGPO 对象,该对象代表您要列出其权限的 GPO。要使用 GetGPOPerms.vbs,您需要将域名 mycompany.net 替换为您的 AD 域的 DNS 名称。请注意,GetGPO 方法的参数是 GPO 的全局唯一标识符 (GUID) 而不是 GPO 的友好名称。在此脚本中,我包括了每个 AD 域中都存在的默认域策略的 GUID。此 GUID 在所有 AD 域中都是相同的。

如果脚本的使用者将要在命令行提供所需的 GPO 信息,那么让他们输入难以键入的 GUID 可能不是一个好办法。一种替换方案是让用户提供 GPO 的友好名称;然后您可以使用 GetGPObyName 函数来获得相应的 GUID,Microsoft 在 Scripts 文件夹的 lib_commongpmcfunctions.js 文件中提供了该函数。GetGPObyName 使用 IGPMSearchCriteria 接口来搜索一个域内的所有 GPO,并返回与输入的友好名称相匹配的 GUID,脚本可以将该 GUID 传递给 GetGPO。但是,GetGPObyName 是一个 JScript 函数。如果您愿意使用 VBScript,您可以编写 VBScript 版本的 GetGPObyName 或使用 IADsTools COM 对象内的 GetGPO、GPOName 和 GPOGuid 方法,IADsTools COM 对象是 Windows 2000 支持工具的一部分。有关这些方法的更多信息,请参见文章 "Scripting with IADsTools",该文于 2003 年 4 月在http://www.winnetmag.com网站发布,InstantDoc ID 38286。

然后,脚本使用 GPMGPO 对象的 GetSecurityInfo 方法检索 GPO 的权限。GetSecurityInfo 方法返回一个对 GPMSecurityInfo 集合对象的引用,脚本把该引用赋值给 GPOSec 变量。GPMSecurityInfo 对象包含分配给 GPO 的权限集。然后脚本遍历整个集合并使用 GPMSecurityInfo 对象的 Count 属性来计数并返回集合中权限项目的数量。

为了检索每一个权限项目,脚本使用 GPMSecurityInfo 对象的 Item 属性,它返回一个对 GPMPermission 对象的引用。当脚本把这个引用赋值给 Ace 变量之后,脚本使用 GPMPermission 对象的 Trustee 属性来访问 GPMTrustee 对象。脚本通过调用 GPMTrustee 对象的 TrusteeName 属性确定分配了当前权限的用户或组的名称,然后把该名称赋值给 PrincipalName 变量。

列表 2 的标注 C 中的代码使用 Select Case 语句来确定分配给该用户或组的安全权限。一个 GPO 可以有五种不同的安全权限,它们是在 IGPMConstants 接口中定义的。Select Case 语句包含这五种权限。

Select Case 语句的第一行告诉 VBScript 运行时引擎把 Ace.Permission 值(即 GPMPermission 对象的 Permission 属性值)与每种情况进行比较。当 Permission 属性值与五个安全权限中的一个相匹配时,脚本把该权限的一个用户友好的描述赋值给 Perm 变量。最后,脚本使用 WSH 的 WScript.Echo 命令把用户或组的名称和权限输出到控制台屏幕。

列表 2 GetGPOPerms.vbs

BEGIN COMMENT
' Create the GPM and GPMConstants objects,
then connect to the domain.
END COMMENT
Set GPMC = CreateObject("GPMgmt.GPM")
Set Constants = GPMC.GetConstants()
‘ BEGIN CALLOUT A
Set GPMCDomain = GPMC.GetDomain("mycompany.net", "",
Constants.UseAnyDC)
‘ END CALLOUT A
‘ BEGIN CALLOUT B
BEGIN COMMENT
' Create an object for the GPO for which you want to list the
permissions.
END COMMENT
Set MyGPO = GPMCDomain.GetGPO
("{31B2F340-016D-11D2-945F-00C04FB984F9}")
BEGIN COMMENT
' Get the permissions.
END COMMENT
Set GPOSec = MyGPO.GetSecurityInfo()
‘ END CALLOUT B
For indx=1 to GPOSec.Count
BEGIN COMMENT
   ' Set the ACE to the Ace variable.
END COMMENT
   Set Ace = GPOSec.Item(indx)
BEGIN COMMENT
   ' Find out the username or group name for the ACE.
END COMMENT
   Set UsrorGrp= Ace.Trustee
   PrincipalName=UsrorGrp.TrusteeName
‘ BEGIN CALLOUT C
BEGIN COMMENT
   ' Find out which permission the user or group has.
END COMMENT
   Select Case Ace.Permission
      Case Constants.permGPOApply
         Perm="Read and Apply Group Policy"
      Case Constants.permGPOEdit
         Perm="Edit Group Policy"
      Case Constants.permGPOEditSecurityAndDelete
         Perm="Edit Group Policy, Modify Security and Delete
Group Policy"
      Case Constants.permGPORead
         Perm="Read Group Policy"
      Case Constants.permGPOCustom
         Perm="Custom Permission"
   End Select
‘ END CALLOUT C
   WScript.Echo "The User or Group: " & PrincipalName & _
      " has the following permission: " & Perm
Next
返回页首返回页首

获取 RsoP 报告

GPMC 的一个非常有用的特性是它执行组策略日志和组策略规划的能力。使用 GPMC 接口,您能够以编程方式从组策略日志和组策略规划会话中获取结果。例如,为了从一个组策略日志会话获取结果,您需要使用 RSoP Windows 管理规范 (WMI) 提供程序。

列表 3 所示的 RSoPLogging.vbs 演示了如何使用 RSoP 接口执行日志查询和创建 HTML 格式的日志报告。脚本的开始几行创建 GPM 和 GPMConstants 对象。然后,脚本使用 GPM 对象的 GetRSOP 方法创建 GPMRSOP 对象的一个实例。此方法采用三个参数,第一个参数指定 RSoP 模式。如列表 3 的标注 A 中的代码所示,提供此模式的一种方法是使用 GPMConstants 对象的 RSOPModeLogging 属性。如果您正在执行一个 RSoP 规划会话,则应改用 RSOPModePlanning 属性。第二个参数指定到先前的 RSoP 数据所在的 WMI 命名空间的路径。在本例中,此参数是一个空字符串,因为不存在先前的数据。最后一个参数总是 0。

在创建了 GPMRSOP 对象的一个实例之后,脚本为 RSoP 日志查询设置两个属性,GPMRSOP 对象的 LoggingComputer 和 LoggingUser 属性。LoggingComputer 属性指定目标机器的名称(在本例中是 myworkstation),而 LoggingUser 属性指定目标用户的名称(在本例中是 Darren)。然后,脚本通过调用 GPMRSOP 对象的 CreateQueryResults 方法(此方法没有参数)执行日志查询。

最后,脚本调用 GPMRSOP 对象的 GenerateReportToFile 方法,此方法采用两个参数。第一个参数指定生成的报告的类型(HTML 或 XML)。脚本使用 Constants 对象的 ReportHTML 属性指定 HTML 报告。如果您希望接收 XML 报告,您可以使用 ReportXML 属性代替 ReportHTML 属性。第二个参数指定报告的路径名。

GenerateReportToFile 方法能够返回一个对 GPMResult 对象的引用。GPMResult 对象有两个属性,Result 和 Status,您可以使用它们确定报告何时结束运行或运行失败。但是,在 RSoPLogging.vbs 中,生成报告是最后一个任务,所以您不需要知道报告何时完成。(当脚本执行完毕时,您就知道报告完成了。)因此,脚本不存储对 GPMResult 的引用。

列表 3 RSoPLogging.vbs

BEGIN COMMENT
' Create the GPM and GPMConstants objects.
END COMMENT
Set GPMC = CreateObject("GPMgmt.GPM")
Set Constants = GPMC.GetConstants()
‘ BEGIN CALLOUT A
BEGIN COMMENT
' Create a reference to an RSoP object.
END COMMENT
Set RSOP= GPMC.GetRSOP(Constants.RSOPModeLogging,"",0)
BEGIN COMMENT
‘ END CALLOUT A
' Set the RSoP logging session’s properties.
END COMMENT
RSOP.LoggingComputer="myworkstation"
RSOP.LoggingUser="darren"
BEGIN COMMENT
' Execute the RSoP logging query and send
the results to an HTML file.
END COMMENT
RSOP.CreateQueryResults()
RSOP.GenerateReportToFile Constants.ReportHTML,
"c:\reports\myrsop.html"
返回页首返回页首

GPMC 带来新的可能

新的 GPMC 接口极为灵活、强大,Microsoft 为它提供了相当齐备的文档。与 Windows 2000 本地工具相比,它们提供了对组策略基础结构的更强的控制能力。如果您创建了自定义脚本并将它们与 Microsoft 提供的脚本结合使用,则可以使大部分 GPO 管理任务自动化。

© 2003 Windows & .NET Magazine。保留所有权利。

浏览 Windows & .NET Magazine 的期刊样本,该样本在以下地址提供:https://secure.pentontech.com/nt/windows/index.cfm?promocode=fs&Code=WI201XTN

Windows & .NET Magazine UPDATE 是免费的电子邮件新闻稿,包含为 Windows IT 专业人士提供的新闻、技巧和其他资源。立即从http://email.winnetmag.com/winnetmag/winnetmag_prefctr.asp订阅。

Microsoft 公司希望本文中的信息对您是有用的。然而,使用本文中包含的信息,您将自行承担风险。本文中的所有信息均按“原样”提供,对其准确性、完整性、特殊目的适用性、所有权或不侵权都没有任何明示或者暗示的保证,并且在本文中 Microsoft Corporation 没有授权、建议、支持或保证任何第三方产品或信息。如果由于您使用本信息造成了任何损坏,无论这些损坏是直接的、间接的、特殊的、偶然的或必然的,即便本文已经提到此类损坏的可能性,Microsoft Corporation 对此概不负责。本文档中提及的产品价格如有变动,恕不另行通知。


返回页首返回页首