windows系统中的组策略相信经常使用电脑的用户应该已经不陌生了吧,但是如何简化对组策略的管理?使用什么技术呢?下文给出了详细的描述。
Microsoft组策略技术不是在一夜间就流行起来的,这一技术在某种程度上比较难以理解,而且需要采用ActiveDirectory,在当时,ActiveDirectory服务才刚刚出现,与当时被奉为标准的Account/Resource域毫无相似之处,人们对此都很陌生。而时至今日,组策略几乎成为每个组织管理Windows®基础结构的主要手段。我有种感觉,WindowsPowerShell™作为Microsoft***的管理技术,将完全肩负起同样的使命,成为主要的管理手段。实际上,WindowsPowerShell很可能会使身为组策略管理员的您工作起来更加轻松。
在本文中,我将为您介绍在WindowsPowerShell中,如何直接使用为VBScript(以及通常基于COM的脚本语言)之类的WindowsScriptingHost语言编写的Microsoft®组策略管理控制台(GPMC)API在自己特有的环境中简化组策略的管理。
为组策略任务编写脚本
几年前Microsoft发布了GPMC,组策略管理员突然发现有许多简便易用的功能可供自己使用。具体地说,以组策略为中心的MMC管理单元体现了组策略管理向前迈进了一大步,特别是相对于使用ActiveDirectory®的用户和计算机而言尤其如此。不仅如此,管理员还可以借助一个全新的API,使用基于COM的语言(如VBScript)来执行组策略管理任务,例如备份和还原组策略对象(GPO)、在域之间迁移GPO、配置有关GPO和链接的安全设置以及编写报告。
但遗憾的是,GPMC并没有提供对组策略对象内实际已配置设置进行编辑的功能。换句话说,您可以对GPO容器执行操作,例如,读取GPO版本、读取修改日期、创建全新的GPO、从不同的域中备份和还原/导入GPO,等等,但却不能以编程的方式添加或更改GPO的内容,例如添加新的重定向文件夹或新的软件安装。通常,您只能使用组策略对象编辑器手动创建GPO并配置所有设置,然后备份该GPO,再将其导入测试环境中。只有当各项功能经过验证可以正常工作时,您才能将其导入实际的应用环境中。尽管缺少这一功能,但使用脚本而不是与GPMCAPI进行人工交互也为日常的策略组管理节省了大量的时间、精力,同时也避免了不少错误。
下一级别
WindowsPowerShell与VBScript之类的脚本语言有何不同?对于初学者而言,WindowsPowerShell是一种外壳程序,至少就目前来说,您可以将其视为一种命令行解释器。尽管VBScript可以从命令行运行,但VBScript文件却不能逐行运行。相比之下,WindowsPowerShell脚本则可以作为一系列单独命令动态地创建。此外,WindowsPowerShell还具有一些功能类似于VBScript中的子例程的函数,它们可在WindowsPowerShell命令提示符下实时地进行创建。
更值得一提的是,WindowsPowerShell基于Microsoft.NETFramework,而VBScript则依赖于早期的COM技术。这意味着,目前有大量的.NET代码可直接在WindowsPowerShell内使用。
总而言之,利用WindowsPowerShell,您可以获得完全的脚本支持和交互模式,多种功能集于一身。本文提供的示例均为命令行输入内容,因此您可以一边看示例一边尝试着输入,不过,如果您将它们放入WindowsPowerShell脚本文件运行,它们也同样能正常工作。
使用WindowsPowerShell重新创建早期脚本
在开始采用一项新技术时,您要做的***一件事就是抛弃以前的全部工作成果。您可以使用三种方法从GPMCAPI访问COM对象,或者主要是重新利用任何早期VBScript。下面是可选的三种方法:
1.使用C#或托管C++等编程语言编写一个WindowsPowerShellcmdlet。
2.使用WindowsPowerShell访问MSScript.ocx中的ScriptControl,以封装早期脚本。
3.将COM调用封装在可重用的WindowsPowerShell函数中或直接调用COM对象。
我将重点介绍第三种方法,但首先让我们简单了解一下所有方法。
创建WindowsPowerShellCmdlet
Microsoft在WindowsPowerShell中放入了大量的cmdlet,这些cmdlet允许您复制文件、将输出内容格式化、检索日期和时间等,但您也可以自己创建cmdlet。有关整个过程的完整详细记录,请访问msdn2.microsoft.com/ms714598.aspx。概括地讲,主要步骤如下所示:
1.使用.NET编程语言(如C#)创建一个类库DLL。
2.创建一个新类并从基类cmdlet继承。
3.设置各种属性,以确定名称、用法、输入参数等,并添加您的代码。
由于WindowsPowerShell基于.NETFramework,任何作为参数返回或传递的类型(如字符串、对象等)在代码中与在WindowsPowerShell中都是完全相同的,不需要进行任何特殊类型的转换。
这一解决方案真正强大之处在于您将拥有一种完全受自己支配的编程语言。
使用MSScript.ocx中的ScriptControl对象封装早期脚本
显然,您需要VBScript引擎来运行VBScript文件。令人不太注意的是,该引擎是COM对象,而且由于您可以从WindowsPowerShell使用COM对象,因此可以调用VBScript引擎。过程如下所示:
- $scriptControl=New-Object-ComObjectScriptControl
- $scriptControl.Language=‘VBScript’
- $scriptControl.AddCode(
- ‘FunctionShowMessage(messageToDisplay)
- MsgBoxmessageToDisplay
- EndFunction’)
- $scriptControl.ExecuteStatement(‘ShowMessage
- “HelloWorld”’)
如果您在WindowsPowerShell命令行界面(CLI)中输入此代码,则会由某参数调用并执行VBScript函数,从而显示一个带有文本“HelloWorld”的消息框。
这时有些人可能会想:“太棒了!我已经掌握了从WindowsPowerShell使用COM的技巧,不用再继续读这篇文章,马上开始使用我的早期GPMC脚本填充ScriptControl对象吧。”很遗憾,事情没有那么简单。随着脚本的增大,这种方法很快就会变得非常复杂而繁琐。
封装COM对象
由此可见,第三种方法是***的:将COM调用封装在可重用的WindowsPowerShell函数中,这样您就能够在GPMCAPI中使用COM对象。下列代码将说明如何直接在WindowsPowerShell中创建.NET对象。在此示例中,可以使用FileInfo对象获得文件的大小:
- $netObject=New-ObjectSystem.IO.FileInfo(
- “C:\boot.ini”)#CreateaninstanceofFileInfo
- #representingc:\boot.ini
请注意,“#”在WindowsPowerShell中用于表示行内注释。使用此新实例化的FileInfo对象,只要键入以下代码即可轻松获得boot.ini的大小:
- $netObject.Length#Displaythesizeinbytesofthe
- #fileinthecommandlineinterface
等等,我们不是说要谈论COM对象和VBScript转换吗?没错,但请看以下命令:
- $comFileSystemObject=New-ObjectCComObjectScripting.FileSystemObject
您会发现,此处的语法与我之前从.NETFramework创建本地对象时所用的基本相同,差别只有两点:***,我添加了CComObject开关,将WindowsPowerShell指向了COM环境,而不是.NET环境。第二,我使用的是COMProgID,而并非.NET构造函数,在本例中为Scripting.FileSystemObject。这里的ProgID是您经常使用的名字。在VBScript中,等同的代码应为:
- SetcomFileSystemObject=CreateObject(
- “Scripting.FileSystemObject”)
若要使用VBScript获得该文件的大小,请将上面的代码行连同以下代码一起添加到一个文件中:
- SetcomFileObject=comFileSystemObject.GetFile(
- “C:\Boot.ini”)
- WScript.EchocomFileObject.Size
然后,使用Cscript.exe等运行它。在WindowsPowerShell中,您可以按如下所示获得文件大小(如果您愿意,可以从WindowsPowerShell命令行直接输入):
- $comFileObject=$comFileSystemObject.GetFile(
- “C:\boot.ini”)
- $comFileObject.Size
当然,我本可以使用管理驱动器内对象的WindowsPowerShellcmdlet对读取文件大小的VBScript进行转换,但我想向您展示从WindowsPowerShell访问COM是多么容易。请注意,虽然我指示WindowsPowerShell创建的是一个COM对象,但实际创建的对象(此处为$comFileSystemObject)是一个封装了该COM对象并公开了其接口的.NET对象。不过,就本文而言,这样做没有任何影响。
运行状态的WindowsPowerShell
现在,您已经知道如何从WindowsPowerShell访问COM,接下来,我们要专门介绍组策略。此处的示例将展示一些简短的代码段,让您对如何从WindowsPowerShell使用GPMCAPI有一个大致的概念;您可以从本文相关的代码下载处,在线为technetmagazine.com/code07.aspx,下载到一整套WindowsPowerShell函数集来管理组策略。图1所列为下载内容中包含的各种函数。
在阅读本节内容时,您可以随意启动WindowsPowerShell命令行并键入命令。但是请记住,有些命令要依赖于前面的命令。也就是说,最初创建的一些对象在以后也会用到,因此,请在同一个WindowsPowerShell会话中执行操作。如果您关闭该会话,则必须从头开始,重新键入所有命令。
好,现在就让我们先用WindowsPowerShell创建一个新的GPO。Microsoft的组策略团队随GMPC提供了许多能够运行正常的VBScript示例,您可以利用它们加快工作速度。这些示例位于%ProgramFiles%\GPMC\Scripts目录中,您还可以在该目录下找到一个包含GPMCAPI文档的gpmc.chm文件。接下来让我们看看CreateGPO.wsf脚本,仔细研究一下它为何能够正常运行。
在脚本的开头,您会发现这么一行:
- DimGPM
- SetGPM=CreateObject(“GPMgmt.GPM”)
这基本上是所有组策略管理会话或脚本的起点,因为是它实例化了GPMgmt.GPM类,从而使大多数GPMC功能都能够被访问。接下来,我们转而从WindowsPowerShell执行这一操作:
- $gpm=New-Object-ComObjectGPMgmt.GPM
现在,您已获得了组策略管理的起点,接下来要了解使用它能够做些什么。通常您需要阅读相关文档来获得此类信息,但WindowsPowerShell提供了一个非常酷的功能。如果键入以下一行,您可以得到如图2中所示的输出:
图2Get-Member输出(单击该图像获得较小视图)
$gpm|gm
我觉得这个功能真的很棒。请注意观察,看Get-Member(orgm)cmdlet是如何允许您直接从命令行查看该对象所支持的属性和方法的。这当然不能等同于阅读文档,但如果您不记得参数的确切个数或确切名称等,该功能可以让您轻松使用熟悉的对象。请牢记一点,在您查看GPMC文档节点列表时,会发现它很象GPM对象,而且所有其他类均带有前缀字母I;这是由于COM的内部工作方式而造成的,我们不需要过分关注这一点;这是专为C++程序员编写本地COM代码准备的,用于表示界面和实现它的类之间的差异。另外还要注意,使用GPMCAPI时,只有一个对象需要您采用此方法来创建,那就是GPMgmt.GPM;其他所有对象均使用该GPM对象开始的方法来创建。
现在,我们要继续创建新的GPO。
图3说明了创建一个GPO是如此的简单。请注意,在这里我省去了一些代码,包括对错误的处理(例如,如果您无权创建GPO会出现什么情况),并且我已对域名进行硬编码,这些都是您应该了解的。
现在,您已经学会如何创建GPO,让我们打开一个现有的GPO。您仍具有对域$gpmDomain的引用,因此请键入以下内容:
- $gpmExistingGpo=$gpmDomain.GetGPO(
- “{31B2F340-016D-11D2-945F-00C04FB984F9}”)
- #OpenanexistingGPObasedonitsGUID,
- #inthiscasetheDefaultDomainPolicy.
- $gpmExistingGpo.DisplayName
- #ShowthedisplaynameoftheGPO,it
- #shouldsayDefaultDomainPolicy
- $gpmExistingGpo.GenerateReportToFile($gpmConstants.ReportHTML,“.\DefaultDomainPolicyReport.html”
上述代码以HTML的形式完整报告了DefaultDomainPolicy中的各项设置,但是很明显,您可以使用任何一种方法和属性(如ModificationTime,它说明该GPO***被修改的时间)来得知该GPO中所有设置的更改时间。
这是非常实用的。例如,您很可能遇到过这类情况:电话疯狂地响个不停,用户纷纷来电抱怨说他们的计算机运转异常。您怀疑这是更改、添加或删除了GPO设置造成的,但没有线索,不知该从哪个GPO着手。此时,WindowsPowerShell可以救急!只要在WindowsPowerShell命令行中输入图4所示的脚本,就可以获得过去24小时内更改的所有GPO。
请注意Cge运算符,它表示大于或等于。如果您习惯使用其他脚本或编程语言中的<和>运算符,可能会有些不习惯。但由于这些运算符主要用于重定向,例如,将输出重定向到文件,因此在WindowsPowerShell中不可将其用作比较运算符。
结束语
图5所列为将一个GPO的设置复制到另一GPO中的完整脚本。现在,您应该能清楚了解如何将这一新技术用于组策略,如何才能重新使用任何COM对象或利用COM对象的VBScript代码。
正如组策略一样,WindowsPowerShell必将成为任何Windows管理环境的组成部分。但面对数百万行需要进行迁移或维护的VBScript代码,希望此教程会对您有所帮助。
您可以使用许多资源来改进组策略管理和其他先前使用VBScript的领域,这些资源包括下载内容中的WindowsPowerShell函数,另外TechNet网站上还提供了VBScript到WindowsPowerShell的转换准则,这一极为实用的准则在您了解VBScript中的等同内容的情况下,可以提示您如何在WindowsPowerShell中执行常见任务。您可以从microsoft.com/technet/scriptcenter/topics/winpsh/convert获得该转换准则。
此外,GPMCAPI也提供完整的文档内容,您可以从组策略网站(microsoft.com/grouppolicy)下载相应的信息。
***但并非最不重要的一点,如果您尚未安装WindowsPowerShell,那还在等什么呢?现在就从下载吧。祝您愉快!
希望本文介绍的使用PowerShell简化组策略管理的方法能够对读者有所帮助,更多有关组策略的知识还有待于读者去探索和学习。
【编辑推荐】