欢迎光临 Enjoy IT (ITECN.NET) 登录 | 注册 | 帮助

PowerShell V2介绍(34) - 最佳操作实践分析模块及Applocker模块

大家好,今天要为大家介绍的是在Windows Server 2008 R2中自带的两个PowerShell模块:最佳操作实践分析模块及Applocker模块。首先我们先来看看最佳操作实践模块。

  • 最佳操作实践模块

大家知道在Windows Server 2008 R2中内置了最佳操作实践分析工具,这是以往只在部分服务器端产品中存在的工具。毫无疑问最佳操作实践分析工具将帮助系统管理员了解当前系统的配置是否满足最佳实践所规定的设置。下面我们就来看看如何使用Windows PowerShell来管理最佳操作实践分析工具。

最佳操作实践分析工具是以PowerShell模块形式实现的,因此我们在使用时首先需要加载模块,具体命令如下:

Import-Module BestPractices -Verbose

从命令行的运行结果中,我们可以看到模块中只有四个cmdlets:Get-BpaMode、Invoke-BpaModel、Get-BpaResult和Set-BpaResult。

01

首先我们先来看看Get-BpaModel。Get-BpaModel的作用就是获得当前PowerShell中所有可用的最佳操作实践分析工具。可以不带参数运行,在返回的运行结果中将显示最佳操作实践分析工具的编号及最近一次运行时间。如果你要获得某个工具的信息的话,可以指定BestPracticesModelId参数,而参数值就是下图中所显示的内容。

02

接下来我们来看看如何在PowerShell中执行最佳操作实践分析工具。涉及到的命令是Invoke-BpaModel。大家可以看到在上图中证书服务和Web服务器都没有执行过最佳操作实践分析,因此我们可以用下面的命令来执行:

Get-BpaModel | ?{$_.LastScanTime -eq "从不"} | Invoke-BpaModel

命令的执行效果如下:

03

当然在以后的日常维护中,我们可以使用任务计划来创建一个任务来定时执行最佳操作实践工具的PowerShell脚本,这样就能方便我们定时跟踪系统及相关服务是不是处在最佳操作实践中。

既然命令已经执行过了,下面我们就来看看如何查看命令的执行效果,也就是最佳操作实践分析工具得出的分析结果。用到的命令是Get-BPAResult。接下来我们就来看一下活动目录的分析结果,命令如下:

Get-BpaResult -BestPracticesModelId "Microsoft/Windows/DirectoryServices" `
| ?{$_.Severity -ne "信息"} | FT Severity,Title -A

这里我们需要注意使用Where筛选出所有严重程度不等于“信息”的项目,因为BPA检测的项目很多,如果有些项目检测通过的话就没必要在最后显示出来。以上命令的执行效果如下:

04

最后我们来看看Set-BPAResult。该cmdlet的作用是用来排除Get-BpaResult中的项目,我们可以排除一些特定的最佳操作实践检查项。下面将用命令排除活动目录最佳实践分析工具分析结果中严重性为信息的分析项。

Get-BpaResult -BestPracticesModelId "Microsoft/Windows/DirectoryServices" `
| ?{$_.Severity -eq "信息"} `
| Set-BpaResult -BestPracticesModelId "Microsoft/Windows/DirectoryServices" -Exclude $true

命令的运行结果如下:

05

最佳操作实践分析模块的使用还是比较简单,下面我们来看看Applocker。

  • Applocker

Applocker也是在Windows Server 2008 R2中新增加的功能,与Windows Server 2003时代的软件限制策略相比,Applocker为管理员提供了更灵活的控制选项。接下来我们就来看看如何来使用PowerShell的Applocker模块。

当然,首先要做的就是使用Import-Module导入Applocker模块,然后我们可以看到Applocker模块中一共有5个cmdlers,分别是:Set-ApplockerPolicy、Get-ApplockerPolicy、Test-ApplockerPolicy、Get-ApplockerFileInformation和New-ApplockerPolicy。

06

在正式测试之前,我们还要启动Application Identity服务,使得Applocker策略能被使用。

然后我们要来看的是Get-ApplockerFileInformation,因为我们需要利用这个cmdlet来为New-ApplockerPolicy准备参数值。Get-ApplockerFileInformation支持从两个源获取信息,分别是文件系统和事件日志。其中在处理文件系统时既能指定一个完整的应用程序路径,也能指定一个目录下符合特定条件的文件集合。接下来我们就来看下具体的命令:

$fileinfo = Get-AppLockerFileInformation -Path C:\Windows\notepad.exe
$dirinfo = Get-AppLockerFileInformation -Directory `
C:\windows\system32\Printing_Admin_Scripts\ -FileType Script -Recurse

以上两条命令分别获得了适用于New-ApplockerPolicy的参数值,第一条是获得记事本的信息,第二条是获得用于管理打印机的脚本信息,接下来在谈到如何从事件日志中得到信息之前,我们需要先应用Applocker策略,并在日志中生成一些信息,然后才能使用Get-ApplockerFileInformation从日志中获得信息。

07

接下来我们就来使用New-ApplockerPolicy创建策略并导出为xml文件。具体命令如下:

New-AppLockerPolicy -FileInformation $fileinfo -RuleType Hash -RuleNamePrefix `
Notepad -User Everyone -Xml > C:\ApplockerPolicy\Notepad.xml
New-AppLockerPolicy -FileInformation $dirinfo -RuleType Hash -RuleNamePrefix `
Printing_Admin_Scripts -User Everyone -Optimize -Xml > C:\ApplockerPolicy\Printing_Admin_Scripts.xml

这里我们使用到了FileInformation参数来导入之前获得的信息,然后在规则类型中指定使用的规则类型是发布者和哈希值,并指定容易辨识的名称,同时指定策略应用给所有人,然后使用XML参数配合重定向符输出策略。两条命令唯一的却别是第二条命令使用了Optimize参数,该参数主要是优化策略,通常在适合在同一文件夹下有多个同一类型的文件需要被限制时使用。

我们可以使用Test-ApplockerPolicy来测试Applocker策略对象,具体命令如下:

Test-AppLockerPolicy -XmlPolicy C:\ApplockerPolicy\Printing_Admin_Scripts.xml `
-Path C:\Windows\System32\Printing_Admin_Scripts\zh-CN\prncnfg.vbs -User EveryOne -Verbose

命令的运行结果如下:

08

这里需要注意的是默认创建出来的策略都是允许用户执行程序的,因此如果有需要的话,我们可以在导入后进行修改。

然后我们再来看看如何使用Set-ApplockerPolicy使策略对象生效。如果在本机使用的话命令很简单:

Set-ApplockerPolicy -XmlPolicy C:\ApplockerPolicy\Notepad.xml -Verbose
Set-ApplockerPolicy -XmlPolicy C:\ApplockerPolicy\Printing_Admin_Scripts.xml -Verbose

命令的运行结果如下:

09

接下来,我们在命令行中刷新下组策略,然后使用Get-ApplockerPolicy查看下当前应用的Applocker策略:

10

接下来,我们就来运行下打印管理脚本,来触发策略,使得Applocker在日志中记录信息。

11

最后我们再来看一下如何从事件日志中获得相关信息,然后再将生产的策略对象整合到组策略中。先来看看代码:

$scriptinfo = Get-AppLockerFileInformation -EventLog -LogPath `
"Microsoft-Windows-AppLocker/MSI and Script" -EventType Denied
New-AppLockerPolicy -FileInformation $scriptinfo -RuleType Path `
-RuleNamePrefix Script -User Everyone -Optimize -Xml > C:\ApplockerPolicy\Scripts.xml
Set-AppLockerPolicy -XmlPolicy C:\ApplockerPolicy\Scripts.xml -Ldap `
"LDAP://CN={D45A7E63-EB0B-4F5A-AF7D-BDA2A59D3038},CN=Policies,CN=System,DC=nwtrader,DC=com" -Verbose

命令的执行效果如下:

12

第一行代码的作用就是从事件日志中提取信息,从事件日志中提取信息时需要为Get-AppLockerFileInformation指定Eventlog参数、日志路径参数及日志类型参数。这里的日志路径参数可以是“Microsoft-Windows-AppLocker/EXE and DLL”或“Microsoft-Windows-AppLocker/MSI and Script”。最终我们将得到的信息保存到$scriptinfo变量中。

第二行代码的作用是新建Applocker策略并导出成xml文件。

第三行代码的作用就是将Applocker策略对象导入到组策略中。实现这个目的需要注意两点。首先你要为Set-ApplockerPolicy指定LDAP 参数指定组策略对象的可分辨名称,其次你需要注意的是必须以具有组策略对象编辑权限的用户执行该命令,否则会收到拒绝访问的错误。

13

至此,按照使用顺序大致为大家介绍了Applocker模块的所有cmdlets,这里最基本的cmdlet是Get-AppLockerFileInformation,它为我们生成Applocker策略的主题,也就是我们需要限制的程序或者脚本信息。接下来就是生成Applocker策略对象并将它应用到本机或者整个域了,总的过程并不复杂,相信大家多使用之后就会掌握的。

由于工作变动的关系,接下来近三个月的时间里面,可能暂时没有时间和精力在为大家分享一些PowerShell的内容了,不过就像美剧也有夏休期一样,在经过夏天的休整之后,相信大家会看到更精彩的内容(可怜的 Dr. Raymond Langston还躺在监狱那冰冷的地上,轻敌的后果……),我们到时见。

发表于 作者 ghjconan | 0 评论

PowerShell V2介绍(33) - 组策略模块(下)

大家好,今天是PowerShell V2组策略模块最后一次介绍,我们将来看一下剩下的所有名词:GPStarterGPO、GPOPermissions、GPInheritance、GPResultantSetOfPolicy、GPOReport。

  • GPStarterGPO

首先我们要来看的是GPStarterGPO,配合这个名词的动词有Get和New。其中Get-GPStarterGPO可以用来获得域中的Starter GPO,我们可以使用Name和GUID参数来获得指定的Starter GPO,但是需要注意的是Name和GUID参数不支持通配符,如果需要得到所有的Starter GPO,则需要使用All参数。比如在下面的例子中我获得了NWTrader域中所有的Starter GPO:

01

当然我们也可以和New-GPO一样新建Starter GPO。同时New-GPStarterGPO的使用也非常简单,我们只需指定Name和Comment参数即可,执行之后会在当前域中创建Starter GPO。不过这里需要注意的一点是,假设在Sysvol文件夹中不存在Starter GPO文件夹,那么New-GPStarterGPO会在Sysvol中创建该文件夹后再创建我们指定的Starter GPO。而假设我们在GPMC中看到这个界面并单击创建按钮后,默认只会用系统自带的Starter GPO来填充该文件夹。

02

而如果我们需要基于Starter GPO创建新的GPO那么可以使用类似以下的代码,先用Get-GPStarterGPO得到Starter GPO对象,然后通过管道传递给New-GPO即可,具体代码如下:

Get-GPStarterGPO -Name NwtraderStarterGPO | New-GPO Shanghai

代码的执行效果如下:

03

  • GPPermissions

接下来,我们来看一下名词部分是GPPermissions的cmdlets。和它搭配的动词有Get和Set。首先我们需要搞清楚的是GPPermissions对应的是GPMC中GPO对象的委派选项卡。我们所要做的修改其最终结果都会反映在这。

04

然后我们使用Get-GPPermissions来验证通过cmdlet得到信息是否和图形界面中的一致。具体代码如下:

Get-GPPermissions -Name Shanghai -All | FT -A

这里需要注意的是All参数代表获得所有安全主体的信息,如果你需要获得单独的安全主体的信息的话,需要使用TargetName及TargetType参数,且TargetType参数的可选值是User、Computer、Group,例如你需要获得System的信息,则应使用以下代码:

Get-GPPermissions -Name Shanghai -TargetName "NT Authority\System" -TargetType User

这里还需要注意TargetName参数的格式。以上代码的执行效果如下:

05

相比使用Get-GPPermissions来获得信息之外,相信大家更关注如何使用cmdlet来进行设置。下面我们就来看看如何使用Set-GPPermissions。我们还是可以通过管道将Get-GPPermissions得到的GPO传递给Set-GPPermissions来进行设置。除了设置刚才指定的TargetName和TargetType参数之外,我们还需要指定PermissionLevel参数来指定具体的权限,PermissionLevel的可选参数值为GpoRead,GpoApply, GpoEdit, GpoEditDeleteModifySecurity 或 None。如果我们需要覆盖原有安全主体的权限的话,则需要使用Replace参数。接下来我们将允许用户组IT对GPO Shanghai拥有编辑权限,那么只需要使用以下代码:

Set-GPPermissions -Name Shanghai -TargetName IT -TargetType Group -PermissionLevel GpoEdit

代码的执行效果如下:

06

  • GPInheritance

接下来我们要来关注的名词是GPInheritance,同GPPermissions一样,我们需要先搞清楚这个名词对应的是GPMC中的哪个标签卡。当然从Inheritance这个单词我们可以马上推断出GPInheritance对应的是组策略继承选项卡。

07

弄清楚具体操作的对象后,接下来我们就来看下如何使用Get-GPInheritance和Set-GPInheritance来处理组策略继承。首先来看看Get-GPInheritance,该cmdlet可以说非常简单,因为它只有一个Target参数需要指定。也可以说不简单,因为在指定参数值时需要以可分辨名称指定对象,所以如果想简化Target的参数值输入就需要你对PowerShell AD Module有一定了解。当然如果你仔细阅读过之前的介绍的话,这不是一件难事。接下来我们就来看一个例子,示例代码如下:

Get-GPInheritance -Target $(Get-ADOrganizationalUnit -Filter {Name -eq "NWTrader"})

代码的执行效果如下:

08

返回的结果中,从上至下依次为对象名称,容器类型,对象的可分辨名称,是否阻止组策略继承,链接的GPO,继承的GPO。熟悉组策略的朋友都知道,GPO能链接到对象是站点,域和OU,因此根据Target参数值的不同,返回的结果中容器对象类型也不同,比如我们要查看应用到域的策略的话,就可以使用以下代码:

Get-GPInheritance -Target $(Get-ADDomain)

代码的执行效果如下,请注意观察ContainerType的值:

09

在说完如何使用Get-GPinheritance来查看组策略的继承情况后,我们再来说说Set-GPInheritance。在没有说之前,相信很多朋友都会期待Set-GPInheritance可以做哪些设置。但是再看了下面的介绍后,可能大家会有些失望。因为Set-GPInheritance的只能调整是否阻止继承组策略。使用起来也很简单,只要指定目标容器然后使用IsBlocked确定是否打断组策略继承。下面我们就以刚才的NWTrader策略为例来进行说明,具体代码如下:

Set-GPInheritance -Target $(Get-ADOrganizationalUnit -Filter {Name -eq "NWTrader"}) -IsBlocked Yes

执行效果如下,大家注意和之前截图的区别。

10

  • GPResultantSetOfPollicy和GPOReport

最后我们再来看看两个和查看GPO设置有关的cmdlets。首先是GPResultantSetOfPollicy,和明显这是用来查看组策略结果集的。一般我们需要设置四个参数,Path、ReportType、User和Computer。Path用来指定报告的存放位置,ReportType用来指定生成的报告类型,有两个可选值XML和HTML,如果你需要对报告做后续处理,那么使用XML是最理想的,如果你只是想看一下特定对象的组策略结果集,那么使用HTML能获得在显示效果上无疑是适合浏览的。而User和Computer对象则用于指定目标用户和计算机。下面我们就来看一个例子,下面一个例子中,将查看用户anna在名为nwtrader-win7的计算机上登录后被应用的策略,具体代码如下:

Get-GPResultantSetOfPolicy -Path C:\Test\a.html -ReportType HTML -Computer Nwtrader-win7 -User anna

至于报告的内容,大家其实很熟悉了,这里就不再截图了。

接下来我们来看看GPOReport。和GPOReport搭配的动词也只有一个Get。Get-GPOReport的作用就是获得组策略的具体设置选项结果,对应的就是GPMC中某一GPO的设置选项卡。在GPMC中我们以HTML视图的方式来查看组策略的设置,而我们通过cmdlet则能生成XML格式的文件。这和Get-GPResultantSetOfPolicy有些类似。下面来看下具体命令:

Get-GPOReport -Name NWtrader -ReportType HTML -Path C:\Test\nwtrader.html

如果要获得所用GPO的报告信息,则可以使用以下代码:

Get-GPOReport -ReportType HTML -Path C:\Test\all.html -All

本次关于组策略模块内置的cmdlets都介绍完毕了,而距离Windows 7和Windows Server 2008 R2正式RTM已经过去快一年的时间了,相信各位已经正在着手准备基础架构的升级工作,那么在升级完毕之后,还是希望大家能经常利用PowerShell来降低自己的工作量,让我们能轻松应对工作中的各种挑战。

PowerShell V2介绍(32) - 组策略模块(中)

大家好,今天要为大家介绍的是组策略模块中名词部分为GPPrefRegistryValue和GPRegistryValue的cmdlets。作为系统管理员的我们都了解组策略的强大,也惊叹于通过组策略我们就能轻松控制组织内Windows系统的一些行为和设置。但有些时候在组织中我们可能还需要通过注册表控制其他软件的一些行为和设置,在Windows Server 2003时代,我们可能会选择使用脚本来修改相关的注册表值,因为组策略中自带的相关注册表设置还是比较孱弱的。自从Windows Server 2008中引入组策略首选项以来,修改注册表变得不再繁琐。但是重复的GUI操作有些时候还是比较让人厌烦的,并且有时我们想要在测试环境中重复这些设置就更会令人心烦意乱。

而在Windows Server 2008 R2中由于PowerShell组策略模块的出现,修改GPO中注册表相关设置的操作变得不再繁琐。而完成具体设置工作的就是名词部分是GPPrefRegistryValue和GPRegistryValue的cmdlets。接下来我们就先来看看设置组策略首选项中注册表的cmdlets,对应的图形界面如下图所示:

01

  • GPPrefRegistryValue

首先我们可以使用Set-GPPrefRegistryValue来创建需要设置的组策略首选项中的注册表设置,使用Set-GPPrefRegistryValue时需要指定组策略对象的名称,Context参数,即是用户配置还是计算机配置,具体注册表键的路径,注册表值名、值以及值类型(可选的值有,String、ExpandString、Binary、DWord、MultiString、ExpandString 和 Qword,和注册表中显示的及以往使用的名称略有不同),及具体操作类型(Create、Update、Replace 或 Delete)。

下面的例子中将在注册表中设置“注册组织”,具体命令如下:

Set-GPPrefRegistryValue -Name Shanghai -Context User -Key "HKLM\Software\Microsoft\Windows NT\CurrentVersion" `
-ValueName RegisteredOrganization -Value " NWTRADER" -Type String -Action Update

命令的执行效果如下:
02

大家可以看到,该cmdlet使用起来还是相对简单的,但是大家也看到了在返回的结果中WMIFilter是一个空对象,想必有朋友就会感兴趣如何去设置这个对象属性了。 但可惜的是目前没有现成的cmdlet支持,同时MSDN上的说明信息也非常有限,我们只能期待下一个版本的GroupPolicy模块了(如果不像2003时代那样独立发布GMPC的话,那我们可能需要等待Windows Server vNext了)。如果要批量设置的话,我们可以使用下面的代码:

Import-Csv .\GPPrefRegistryValue.csv | %{Set-GPPrefRegistryValue -Name $_.Name `
-Context $_.Context -Key $_.Key -ValueName $_.ValueName -Value$_.Value -Type `
$_.Type -Action $_.Action}

和批量创建用户一样,我们可以先准备一个csv文件,然后把对应的内容写入该文件,然后使用Import-CSV导入,并通过管道传递给Set-GPPrefRegistryValue进行设置。命令的执行结果如下:

03

其中GPPrefRegistryValue.csv的内容如下:

Name,Context,Key,ValueName,Value,Type,Action
Shanghai,User,"HKLM\Software\Microsoft\Windows NT\CurrentVersion",RegisteredOrganization,"NWTRader","String",Update
Shanghai,User,"HKLM\Software\Microsoft\Windows NT\CurrentVersion",RegisteredOwner,"NWTRader Users","String",Update

因此如果有大量注册表设置需要导入的话,最好使用以上方法,同时该方法也解决了生产环境与测试环境设置同步的问题,我们只需保留好相应的CSV文件即可。

接下来,我们可以用Get-GPPrefRegistryValue来确认刚才的创建工作有没有完成,具体命令如下:

Get-GPPrefRegistryValue -Name Shanghai -Context User -Key `
"HKLM\Software\Microsoft\Windows NT\CurrentVersion" | fl FullKeyPath,ValueName,Value

命令的运行结果如下:

04

最后我们再来看下如何删除以上的注册表首选项设置,我们首先需要使用Get-GPO得到组策略对象,然后将组策略对象通过管道传递给Remove-GPPrefRegistryValue删除即可,删除时需要指定Context及Key参数,具体命令如下:

Get-GPO Shanghai | Remove-GPPrefRegistryValue -Context User -Key `
"HKLM\Software\Microsoft\Windows NT\CurrentVersion"

命令的执行效果如下:

05

  • GPRegistryValue

接下来我们再来看一下另外一个和组策略注册表有关的名词GPRegistryValue,这里需要注意的是通过名词部分是GPRegistryValue设置的项目是不会出现在GPO编辑器的GUI界面中的(因为没有对应的模板),但是我们可以在GPMC的RSoP标签中查看,如下图所示:

06

具体设置命令如下:

Set-GPRegistryValue -Name Shanghai -Key "HKLM\Software\Microsoft\Windows NT\CurrentVersion" `
-ValueName RegisteredOrganization -Value "NWTrader" -Type String

而如果需要禁用注册表设置,并从客户端删除相关设置,则可以使用Disable参数禁用。命令的执行效果如下:

07

如果你只需从组策略中删除相关设置,并且需要保留客户端已经应用的设置,则需要使用Remove-GPRegistryValue来删除,具体命令如下:

Remove-GPRegistryValue -Name Shanghai -Key "HKLM\Software\Microsoft\Windows NT\CurrentVersion"

命令的执行效果如下:

08

相较而言,我想大家还是会喜欢通过组策略首选项来设置注册表。本次关于组策略模块中注册表相关设置的cmdlets的介绍就到此结束了,敬请期待下次的介绍。

PowerShell V2介绍(31) - 组策略模块(上)

大家好,截止到上次介绍为止,我们已经走马观花般的了解了PowerShell AD 模块中的所有cmdlets。从本次介绍开始,我们将开始了解如何使用PowerShell来管理组策略。同之前AD模块的介绍一样,首先要确定的是组策略模块中包含哪些cmdlets。具体命令如下:

Import-Module GroupPolicy
Get-Command -Module GroupPolicy | Group-Object Noun

命令的运行结果如下:

01

首先我们需要导入组策略模块,因为默认情况下PowerShell是不会加载组策略模块的。接下来我们使用Get-Command并配合Module参数来显示组策略模块内所有的cmdlets。按照之前学习AD模块同样的方法,这里再次使用Group-Object cmdlet对cmdlets的名词部分进行分类汇总,帮助我们制定学习计划。今天就先来看看名词部分是GPO和GPLink的cmdlets。

名词部分是GPO的cmdlets共有八个,如下图所示:

02

这八个cmdlets再细分的话可以分为两类,一类是用于GPO基本管理的cmdlets,即动词部分是New,Get,Copy,Remove和Rename的cmdlets。剩下的Backup,Import及Restore则构成用于GPO备份和还原的cmdlets。下面就先来说说用于GPO基本管理的cmdlets。

按照之前的思路,我们首先可以使用New-GPO来创建一个新的GPO。相对于New-ADUser来说,New-GPO使用起来还是相当简单的。我们可以使用以下命令来创建新的GPO:

New-GPO -Name "Shanghai"

当然一般情况下,我们会为GPO添加注释,以便存在大量GPO时能精确的知道GPO的用处。因此修改后的命令如下:

New-GPO -Name "Shanghai" -Comment "GPO for Shanghai Users"

命令执行后将返回GPO对象,而如果不通过管道传递对象的话,PowerShell将显示GPO的一些信息:

03

总的来说创建GPO还是很简单的,当然现在仅仅是创建了GPO,要想让GPO生效还必须将GPO链接到站点,域或者组织单元。这部分任务将由名词部分是GPLink的cmdlets完成,稍后再来介绍。

大家知道从Windows Server 2008开始在GPMC中新增加了一个Starter GPO的容器。Starer GPO类似GPO模板的一个集中存储地,我们可以将一些基本设置以Starter GPO形式保存在该容器中,然后根据该Starter GPO来创建具体应用到对象上的GPO。默认情况下系统会自带几个根据安全性指南创建的Starter GPO,我们也可以创建自己的Starter GPO,然后在使用New-GPO时使用StarterGpoName参数来引用。具体命令如下:

New-GPO -Name "Shanghai" -Comment "GPO for Shanghai Users" -StarterGpoName "NWTraderStarterGPO"

总的来说新建GPO并不复杂,接下来我们要了解如何得到GPO对象。当然这也很简单,使用Get-GPO cmdlet即可。Get-GPO可以使用Name或者GUID得到具体GPO对象,或者在执行Get-GPO时使用All参数则将返回所有GPO对象。

04

当然Get-GPO除了返回GPO的信息外主要还是用来执行后续操作,也就是为Copy-GPO,Rename-GPO和Remove-GPO提供对象。下面的截图就是以上三个cmdlets的执行过程。这里需要注意的是Copy-GPO的CopyACL参数,使用该参数将复制源GPO的安全筛选。

05

说完用于基本GPO管理的cmdlets之后,我们再来看看用于备份和还原GPO的cmdlets。很明显备份GPO肯定是用Backup-GPO。我们可以使用以下命令来备份所有的GPO并在注释中指定相关备份信息。具体命令如下:

Backup-GPO -All -Path E:\GPOs -Comment "Weekly Backup"

命令的执行过程如下,注意默认将返回每一个GPO的备份信息。

06

当然一般我们是用任务计划来执行定时备份的,因此这些返回信息也没什么太大影响。下面就顺便提一下如何使用schtasks来创建执行定时备份的任务。

schtasks /Create /SC WEEKLY /TN "GPO Backup" /TR "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File 'C:\PowerShell\GPOBackup.ps1'" /RU SYSTEM /ST 00:00

当然也可以使用图形界面来创建任务,这里的关键就是明白任务计划要执行的命令是PowerShell脚本,然后需要将执行的cmdlets通过Command参数传递给PowerShell。这里最好让PowerShell运行一个ps1脚本文件,如果你直接使用Command参数传递命令的话,命令中的引号可能会让你无所适从。脚本中的代码如下:

Import-Module GroupPolicy
Backup-GPO -All -Path E:\GPOs -Comment "Weekly Backup"

接下来我们把名为Shanghai的GPO删除,然后分别使用Import-GPO和Restore-GPO来还原。首先我们可以使用Import-GPO从备份中导入备份的Shanghai GPO,具体命令如下:

Import-GPO -BackupGpoName Shanghai -TargetName Shanghai -Path E:\GPOs -CreateIfNeeded

执行效果如下:

07

这里需要指定备份中GPO的名称,恢复时使用的名称,备份文件所在的文件夹路径。同时因为这里我们删除了Shanghai这个GPO,因此还需加上CreateIfNeeded参数。如果你只是为了恢复GPO中的设置,且GPO没有被删除,则可以不使用该参数。

下面我们再来谈谈如何使用Restore-GPO cmdlet。想必很多朋友从字面上会认为Restore比Import更有用,因为他执行的是还原操作,同时也会下意识的认为如果我误删了一个GPO用Restore-GPO cmdlet肯定能还原回来。但是这里不得不提醒各位注意了,Restore-GPO的作用仅仅是从一个或多个 GPO 备份文件还原域中的一个或全部 GPO,如果GPO不存在则Restore-GPO会失败:

08

因此如果要恢复误删除的GPO的话还是需要使用Import-GPO cmdlet从备份中导入被误删的GPO。

说完了和GPO管理有关的cmdlet之后,今天剩下来的时间我们将来看看名词部分是GPLink的cmdlets。GPO存在的意义就是管理员希望容器中的对象会应用GPO中的设置,如果仅创建GPO而不链接具体容器,那么创建再多GPO也是没意义的。下面我们就来看看如何使用名词部分是GPLink的cmdlets。

首先我们先来看看New-GPLink。使用New-GPLink需要指定GPO的名称及目标容器的可分辨名称。其它重要的参数还有Order,enforced及LinkEnabled,分别对应组策略优先级,是否强制组策略生效及是否启用链接。接下来我们就来将之前新建的名为Shanghai的GPO应用到相应的OU:Shanghai。具体命令如下:

New-GPLink -Name Shanghai -Target (Get-ADOrganizationalUnit -Filter {Name -eq 'Shanghai'})

这里在指定Target时利用到之前的AD Module中的cmdlet,如果大家执行以下命令失败的话,请注意是否导入了AD Module。

以上命令的执行效果如下:

09

然后我们来看一下New-GPLink的逆操作Remove-GPLink。同样的在使用Remove-GPLink时需要指定Name和Target参数,具体命令只要把之前New-GPLink -Name Shanghai -Target (Get-ADOrganizationalUnit -Filter {Name -eq 'Shanghai'})中的new-gplink替换成Remove-GPLink即可。

最后我们再来看下Set-GPLink。Set-GPLink的作用就是设置之前我提到的Order,enforced及LinkEnabled这三个属性。同样在使用时需要指定Name和Target参数。下面就来看一个例子:

Set-GPLink -Name Shanghai -Target (Get-ADOrganizationalUnit -Filter {Name -eq 'Shanghai'}) -LinkEnabled No

执行效果如下:

10

这里需要注意的是LinkEnabled的可选值是Yes,No及Unspecified,千万不要想当然的设置成$True和$False。

本次关于PowerShell V2 Group Policy 模块的介绍就到此结束了,敬请期待下次的介绍。

 

PowerShell V2介绍(30) - 在活动目录中查找对象

大家好,通过这几次的介绍,我们已经大致了解了PowerShell AD Module中的所有cmdlets,同时也已经熟悉了一些基本的使用原则比如“得到对象,然后对对象进行操作”。今天我们就重点来看看如何得到对象,因为这是一切操作的前提。而要想精确得到对象,那么熟练使用Get-AD* cmdlets的Filter参数就是必须要要掌握的。本次介绍将以“about_ActiveDirectory_Filter”帮助文件中的内容为蓝本来进行,大家在阅读本文的同时也可以看下自带的帮助。

首先我们要确认的就是哪些cmdlets支持Filter参数,之前都是从介绍每个cmdlet出发,如果遇到可以使用Filter参数的cmdlet便会根据具体的例子稍作介绍,现在我们需要从全局的角度来了解下到底哪些cmdlets支持Filter参数。当然这个问题用PowerShell也是很容易解决的,使用的技巧在之前介绍事务日志时也使用过,即通过帮助文件的中的内容来定位参数列表中包含Filter的cmdlet,具体命令如下:

Get-Help *-AD* -Parameter Filter

命令的执行结果如下:

01

在帮助中有这么一句话“大多数 Get-AD* Active Directory 模块 cmdlet 都使用 Filter 参数来搜索对象。”我们还是可以用PowerShell来验证下这句话是不是对:

02

可能40%离“大多数”还是有点差距,不过在实际使用中我们可以使用自动补完功能来确认一个cmdlet是不是支持Filter参数。

确认完支持Filter参数的cmdlets后,我们就来看看如何设置Filter参数的参数值。一般情况下下参数值可以是以下形式:

{(属性名 筛选操作符 值)[ 逻辑操作符 (属性名 筛选操作符 值)]}

这里的属性名可以使用“属性编辑器”来确认。而筛选操作符中常用的就是用于判断当前属性值与给定值是否完全相等的-eq和-ne,判断两者之间大小关系的-lt,-le,-gt及-ge,以及支持模糊查找的-like及-notlike参数。一般我们会在精确匹配时使用-eq及-ne操作符,比如查找具有相同职位信息的员工。而判断大小关系很多时候则用在数值比较上,比如判断用户的密码是否快过期了,然后是不是需要发送邮件通知用户。而当我们想查询整个公司所有的经理级人员时可以使用支持模糊查询的-like或者-notlike操作符,因为可能在指定具体职位信息时是使用了“XXX部门经理”这样的内容,如果使用精确匹配会无法得到我们想要的结果。

这里还有一个操作符需要提一下,-recursivematch。这个操作符会帮助我们确认在组嵌套的情况下,用户是否隶属于该组,不过需要Windows Server 2008的支持。

前面几个操作符使用起来很简单,相关的例子在之前的介绍中就出现过很多次了,接下来我们就来就通过一个例子看下-recursivematch。

现在假设在文件服务器上为研发人员开设了一个名为DEV的文件夹,并设置ACL_FS_DEV_ReadOnly安全组具有读取权限,而研发人员分散在很多部门之中,因此利用组嵌套将代表研发各个部门所在的用户组加入到ACL_FS_DEV_ReadOnly这个组中。然后某一天研发部门的一位同事告诉你他无法访问DEV文件夹,在排除其它可能原因之后,我们就需要确认该用户是不是ACL_FS_DEV_ReadOnly这个组中的成员了。具体命令如下:

$GroupDN = Get-ADGroup -Identity ACL_FS_DEV_Readonly
$UserDN = Get-ADUser -Identity BJUser001
Get-ADUser -Filter 'memberOf -RecursiveMatch $GroupDN' -SearchBase $UserDN

为了简化筛选器的筛选条件,这里我先将对象的可分辨名称存入变量中。然后再在Get-ADUser中设置筛选器。这里还是可以按照之前的格式指定筛选器的参数值,需要注意的就是将筛选操作符设置为-RecursiveMatch,同时指定SearchBase的参数值为某一用户的可分辨名称。如果用户位于该组中则返回用户对象。代码的执行效果如下:

03

通过使用筛选器来执行此类任务的效率高于通过遍历组成员来判断用户是否在该组中,因此也请大家善加利用-RecursiveMatch这个筛选操作符。

接下来要看一下控制搜索范围的两个参数SerachBase和SeacrhScope。SerachBase用于控制搜索的广度,比如说Contoso集团在上海和北京各开设了两家分公司,各分公司都设有财务,销售,人力等部门。假设有一天我们要为这两家分公司下的所有员工都设置公司属性,那么就可以设置SearchBase的参数为代表具体分公司的OU的可分辨名称,保证对各分公司用户进行正确的修改。而SearchScope参数则是用来控制搜索的深度,我们可以通过一张图来说明:

04

默认情况下SearchScope的参数值是Subtree,也就是搜索通过SearchBase所指定对象的所有子对象。

接着我们来看一下ResultPageSize 和 ResultSetSize这两个参数。根据帮助信息中所描述“ResultPageSize 指定返回的每个信息页中包含的最大对象数”。这句话看上去有点难以理解,实际上我们可以从设置这个参数的目的来理解这个参数。假设某次搜索结果返回了1000个对象,在实际查询请求中,这个1000个对象不是一次性返回的,而是每次返回256个(ResultPageSize的默认值)对象,而这256个对象就组成了一个信息页。每一个信息页之间都会有一定的时间间隔,这样做的目的就是避免瞬间大量的查询请求造成服务器过载。当然这个时间间隔可能你无法感觉出来,而且现代服务器的处理能力使得你觉得结果就是一瞬间返回的。因此除非有特殊需要,我们可以不设置这个参数,使用默认值即可。

而ResultSetSize则是用来控制返回的对象总数,使用过Exchange 2007的朋友肯定会设置过下图中的设定:

image

其实这个限制就和查询时的ResultSetSize有关,常见的默认值就是1000。不过在PowerShell AD Module中这个设置的默认值是$null,也就是没说没有限制。

最后说两个增加搜索速度的小提示。首先最重要的一点就是确定你所要操作的对象的具体位置,然后使用SearchBase参数指定这个位置,换句话说就是如果你只是操作Contoso集团下的上海分公司,就需要将上海分公司组织单元的可分辨名称作为SearchBase的参数值。其次如果你需要在筛选器中使用对象类别来筛选对象,那么应当使用objectCategory而不是objectClass,这是因为objectCategory在数据库中是被索引的。更多提示可以参考Creating Efficient Queries

至此关于PowerShell AD Module的介绍就暂时告一段落了,从下次介绍开始,我们将看一下如何使用PowerShell来管理组策略,敬请期待。

PowerShell V2介绍(29) - ADObject、ADOptionalFeature和ADRootDSE

大家好,今天要为大家介绍的是PowerShell AD Module中的最后三个名词:ADObject、ADOptionalFeature和ADRootDSE。虽然名词数量少,但是cmdlets数量却不少,我们可以使用以下命令来看一下一共有多少个cmdlets:

Get-Command *ADObject, *ADOptionalFeature, ADRootDSE | Sort Noun | FT -a

01

可以看到上述命令供返回11个cmdlets,其中ADObject占了七个。下面我们就先来看看名词部分是ADObject的cmdlets。

  • ADObject

相信通过前几次的介绍,各位对如何使用cmdlets来管理活动目录域服务中的用户、组及组织单元都有所了解了。在之前的介绍中涉及到了新建这些对象,为这些对象设置属性值及删除对象这三个操作。但是在实际的管理操作中,还有两个操作也是很常见的,一是移动用户、组及组织单元,二是重命名用户、组及组织单元。但是我们没有看到类似Move-ADUser、Rename-ADGroup的cmdlets,不知道各位在看之前的介绍时有没有产生这样的疑惑?

仔细想一下也不难理解,因为移动和重命名操作不单单只针对一种对象类型,如果单独为每一个对象类型分别加上动词是Move和Rename的cmdlets会有点浪费。同时在活动目录域服务的管理中,虽然系统管理员在用户、组和组织单元上所花的管理时间是最多的,但是有时候也需要管理其它对象,因此PowerShell AD Module的开发团队便设计了ADObject这个名词来代替其它人工管理频率比较低的对象,以便让用户在使用PowerShell进行管理时获得一致的体验。下面就通过创建子网对象这个具体的例子来看一下如何使用名词部分是ADObject的cmdlets。

毫无疑问创建子网对象使用的cmdlet是New-ADObject,在使用New-ADObject时必需要指定对象的名称和类型,而子网对象的类型名称(架构类的LDAP显示名称)是subnet,我们可以使用“Active Directory 架构”来确定。

02

虽然可以使用New-ADObject来创建架构类中所定义的任意对象,但是使用的前提也很明确,你必须理解每个类的用法和必要属性,这对很多系统管理员来说可能会有点困难,因此这里选择的是子网这个对象,因为子网对系统管理员来说还算是比较面熟的对象。创建子网对象的代码如下:

New-ADObject -Name "192.168.100.0/24" -Description "Shanghai" `
-Type "subnet" -Path "CN=Subnets,CN=Sites,CN=Configuration,DC=Test,DC=Com" `
-OtherAttributes @{siteObject="CN=Shanghai,CN=Sites,CN=Configuration,DC=Test,DC=Com"} `
-Verbose

运行效果如下:

03

这里还需要注意的是如果要让新建的子网对象与站点关联的话必须使用OtherAttributes参数为子网对象设置siteObject属性,而siteObject属性的值则是站点对象的可分辨名称(distinguishedName)。虽然不这么做也能创建出子网对象,但是如果你在图形界面中创建子网对象的话你会发现必须要指定相应的站点,因此在使用New-ADObject创建时,我们应当遵循这一规则。

这里还引出一个问题,就是如何得到站点的可分辨名称。这个问题,我们可以使用Get-ADObject来轻松解决。因为Get-ADObject从cmdlet名称上来看就是得到AD中的对象,那么得到和站点有关的信息自然不在话下。下面我们就来看看如何使用Get-ADObject来得到站点对象,从而得到站点的可分辨名称。

和其它动词是Get的cmdlets一样,Get-ADObject可以使用Filter及LDAPFilter来获得对象,这里我们使用LDAPFilter参数来得到站点对象,具体命令如下:

Get-ADObject -Filter "(objectCategory -eq 'site') -and (name -eq 'Shanghai')" `
-SearchBase "CN=Configuration,DC=nwtrader,dc=com" | fl *

命令的执行效果如下:

04

这里除了注意Filter参数的值要设置正确之外,还需要设置SearchBase参数来指定搜索位置。

接下来我们来看看如何使用Set-ADObject。之前在使用New-ADObject创建子网对象时我说过通过PowerShell创建子网对象时可以不指定关联的站点,不过这不是最佳操作实践,但是万一一不小心建立一个没有和站点关联的子网对象,我们除了删除重建之外,还有没有办法弥补呢?当然,Set-ADObject就能解决,不过我们还是需要使用Get-ADObject来得到对象。具体命令如下:

Get-ADObject -Filter "(objectCategory -eq 'subnet') -and (name -eq '172.16.100.0/24')" `
-SearchBase "CN=Configuration,DC=nwtrader,dc=com" | Set-ADObject `
-Add @{siteObject="CN=Shanghai,CN=Sites,CN=Configuration,DC=nwtrader,DC=com"} -Verbose

命令的执行效果如下:

05

同样的由于是针对所有对象的操作,因此Set-ADObject使用Add,Replace,Remove参数配合哈希表@{attribute=value}来设置对象的属性。不过Set-ADObject还有一个特别有用的参数是ProtectedFromAccidentalDeletion,相信大家也知道这个参数的作用了,是的,除了组织单元之外,我们能对AD中所有重要的对象,无论是用户,组还是子网对象设置防止意外删除标记,这对AD管理员来说无疑是个好消息。

接下来,我们就来看下ADObject所特有的两个动词Rename和Move。Rename-ADObject可能大家认为不需要多做什么解释,一看便知就是重命名AD对象的。但是需要注意的是,该cmdlet只修改对象的Name属性。如果被修改对象是用户、计算机或者组,该cmdlet将不会修改姓,名,显示名,及sAMAccountName,和图形界面提供给我们的一个统一修改界面相比还是有所不同的。下面我们就来看看Rename-ADObject的示例,并看看是不是只修改了Name属性:

06

而Move-ADObject的使用也不复杂,我们需要先得到需要移动的对象,然后使用TargetPath参数来指定目标容器,接下来我们就来看看如何将admin001这个用户移动到默认的用户容器中。具体代码如下:

Get-ADUser admin001 | Move-ADObject -TargetPath “cn=users,dc=test,dc=com”

命令的执行效果如下:

04

刚才提到了防止对外意外删除的参数,这里顺便提一个问题。如果朋友正在尝试从Windows Server 2003 升级到Windows Server 2008 R2,并且已经用过Windows Server 2008 R2活动目录的BPA工具的话,想必可能会为下图的警告感觉到不爽(BPA出来的结果可能绝大部分朋友都希望全绿通过)。

05

这个问题,我想大家已经有答案了吧?我们可以直接用以下命令来解决:

Get-ADOrganizationalUnit -Filter * | Set-ADOrganizationalUnit -ProtectedFromAccidentalDeletion $true

至此,与ADObject搭配的动词就剩Remove和Restore没有介绍了,而Remove-ADObject相信大家不用我介绍也知道怎么使用了。而Restore-ADObject在介绍AD回收站时,将详细介绍,这里就暂且放一下。

  • ADRootDSE

接下来我们要介绍的是Get-ADRootDSE。该cmdlet主要用来获得活动目录的相关信息,可以不加参数直接运行,获得的信息如下(截图中只包含部分属性):

06

在上图中红线划出的两个属性对需要编写在不同域环境中运行同一个脚本的朋友来说很有用,因为之前在Get-ADObject的介绍中,大家已经注意到在搜索某些对象时,我们需要指定SearchBase参数,而这些参数值可能会因为拼写错误而经常写错,因此我们可以使用Get-RootDSE来得到包含这些属性的对象,然后将相关值赋值给变量,这样我们便能重复在命令中使用了。

  • AD回收站

接下来要为大家介绍的就是在Windows Server 2008 R2中活动目录域服务最新增加的一项功能:AD回收站。毫无疑问AD回收站和防止意外删除选项构成了双保险,使得因为系统管理员误删帐号而造成的意外宕机事件降低了最低限度。下面我们就来看看如何使用AD回收站来还原被意外删除的对象。

使用AD回收站的先决条件是活动目录域服务的林功能级必须是Windows Server 2008 R2,也就是说林中的所有域控制器必须全部是Windows Server 2008 R2,相信等Windows Server 2008 R2大范围部署之后,要达到这个先决条件没什么困难。然后AD回收站功能默认是被禁用的,虽然可以通过多种方法来开启,但相较来说使用PowerShell开启还是很简单的,接下来我们就来看看如何使用名词部分是ADOptionalFeature的cmdlets来管理AD回收站功能。

首先使用的cmdlet是Get-ADOptionalFeature,具体命令如下:

Get-ADOptionalFeature -Filter *

执行结果如下:

07

大家可以看到从返回的信息中我们可以确定在Windows Server 2008 R2中活动目录域服务只带了AD回收站这一功能。同时我们还可以了解到AD回收站这项功能在启用之后是不能被禁用的(IsDisableable)。这一点,我们可以在下面使用Enable-ADOptionalFeature时得到验证。具体命令如下:

Get-ADOptionalFeature -Filter * | Enable-ADOptionalFeature -Scope ForestOrConfigurationSet -Target test.com

命令执行后,大家便能看到相关警告告知AD回收站功能无法被禁用。

08

在按回车确认启用AD回收站这项功能之后,我们便能看看如何使用AD回收站来还原被删除的对象了。当然在这之前,可能会有朋友质疑,如果AD回收站功能不能被禁用,那么Disable-ADOptionalFeature cmdlet不是没有任何作用了么?现阶段来说的确是这样,但是将来一旦有新的功能增加进来之后,我们便能使用这个cmdlet了,现阶段我们暂且可以不管这个cmdlet。

09

接下来我们就来看看如何使用Restore-ADObject来还原被删除的对象。当然没有删除哪来还原,我们首先要做的就是删除一个对象,这可以用动词为Remove的cmdlets来删除对象。现在就让我们先来删除一个用户对象,具体命令如下:

Get-ADUser admin002 | Remove-ADUser

接着我们就需要使用Restore-ADObject来还原被删除的对象了,当然按照一贯的操作原则“得到对象,然后对对象进行操作”,现在要做的就是得到被意外删除的用户对象test。那么自然而然的会想到使用动词是Get的cmdlet,那是不是还是Get-ADUser呢?当然不是,因为被意外删除的对象不一定都是用户对象,而且因为要查找的是被删除的对象,所以我们需要使用Get-ADObject cmdlet并且需要加上参数IncludeDeletedObjects。并且为了精确定位被删除的对象,我们需要使用Filter参数,然后将找到的对象通过管道传递给Restore-ADObject,具体命令如下:

Get-ADObject -Filter {sAMAccountName -eq ‘admin002’} -IncludeDeletedObjects | Restore-ADObject -Verbose

命令的执行结果如下:

10

大家可以注意下被删除的对象是从哪个位置被还原回到原始配置的。接下来可能还有一个疑问,被删除的对象会保留所有被删除之前的属性么?下面我们就来看看一个用户组被删除然后再被还原后它的组成员会不会发生变化。

具体验证过程如下,首先确认IT组中的成员,然后删除IT这个组,接着使用Get-ADObject从已删除对象容器中找到被删除的IT组,并执行还原操作。最后我们再次确认IT组中的成员是不是依然存在。

11

最后可能还有一个问题,就是如果用户删除了一个OU,而该OU下又包含很多对象,这时该如何执行还原操作呢?由于活动目录中的对象具有层次结构,想要还原下级子对象就必须先还原该子对象的上一级对象。也就是说如果想要还原一个被删除OU下的用户对象的话,首先必须还原该OU。可能听上去很复杂,不过好在活动目录回收站循序渐进指南附录B中为我们提供了一个样例脚本可以帮助我们还原,大家可以参考下。

至此,PowerShell AD Module中所有的cmdlets都为大家进行了介绍。在下一次的介绍中,我们将仔细看看如何使用Filter参数,敬请期待。

PowerShell V2介绍(28) - 密码策略

大家好,今天要为大家的介绍的是和密码策略有关的cmdlets。涉及到的名词有ADDefaultDomainPasswordPolicy、ADFineGrainedPasswordPolicy、ADFineGrainedPasswordPolicySubject和ADUserResultantPasswordPolicy,可以使用Get-Command *PasswordPolicy* | FT -a来查询所有命令,最终共返回10个cmdlets:

01

其中和精细化(颗粒化,或者命令帮助里翻译成的细粒化)的密码策略有关的cmdlets有七个,等下会详细介绍它们。然后有两个是和默认的域密码策略有关,最后一个则是用来查询用户密码策略的应用结果。下面我们就先来看看和默认的域密码策略有关的两个cmdlets。

  • ADDefaultDomainPasswordPolicy

搭配ADDefaultDomainPasswordPolicy的动词有Get和Set,比常见的四个动词一个名词的cmdlet少了两个名词,New和Remove,当然这也很好理解。下面我们按照以往的思路看看Get-ADDefaultDomainPasswordPolicy能提供什么样的信息。

02

当然各位不看前面的英文单词,从后面的属性值就能知道这是密码策略中的哪个属性,上图中就是一个默认的没有经过修改的密码策略。而该cmdlet也没有特别的参数需要我们进行设置的。因此接下来我们就来看看如何使用该cmdlet配合Set-ADDefaultDomainPasswordPolicy来修改默认的域密码策略。先来看下具体命令:

Get-ADDefaultDomainPasswordPolicy | Set-ADDefaultDomainPasswordPolicy `
-ComplexityEnabled $true -LockoutDuration 00:30:00 -LockoutThreshold 5 `
-MaxPasswordAge 30.00:00:00 -MinPasswordAge 0.00:00:00 -MinPasswordLength 8 `
-PasswordHistoryCount 5 -ReversibleEncryptionEnabled $false -V

命令看上去很复杂,其中一点就是时间值的格式,需要使用 天.小时:分:秒 来指定。但这么复杂的命令实际上就是修改我们在图形化界面中所修改的默认域策略里面的设置,命令运行的结果如下:

03

如果此时你在GPMC中查看默认域策略的话,你会发现相关的密码策略的属性都被修改了:

04

  • ADFineGrainedPasswordPolicy

接下来我们就来看看如何使用cmdlets来管理精细化的密码策略。精细化的密码策略在Windows Server 2008中第一次被引入,主要用来解决系统管理员在实际的管理活动中所面临的不同密码强度需求。不过在Windows Server 2008中系统自带的创建向导不怎么人性化,每设置一个选项都需要管理员单击下一步按钮,因此在随后的几个月中相关的第三方管理工具便出现了。而在Windows Server 2008 R2中我们可以通过PowerShell带给我们的良好操作体验来解决这个问题。下面我们就来看看如何使用cmdlet来创建精细化的密码策略。

先来看看新建代码:

New-ADFineGrainedPasswordPolicy -Name "ITAdminsPSO" `
-Precedence 100 -Description "Password Policy for IT Admins" `
-DisplayName "Password Policy for IT Admins" -MinPasswordLength 12 -Verbose

运行效果如下:

05

通过运行结果我们可以看到精细化的密码策略对象是创建在名为“Password Settings Container”的容器中。而之前代码中指定的Precedence参数则是用来决定当多个精细化密码策略应用到同一个对象时该应用哪个策略,该参数值必须是10或100的倍数。在最后介绍Get-ADUserResultantPasswordPolicy cmdlet时将通过一个例子来看看这个参数作用。

接下来,我们使用Get-ADFineGrainedPasswordPolicy来查看我们刚才创建的精细化密码策略对象,代码如下:

Get-ADFineGrainedPasswordPolicy -Identity ITAdminsPSO

运行后将返回以下信息:

06

这里大家可以注意到由于之前我在新建的时候只指定了密码长度参数,因此返回的结果中只有密码长度这一项被修改了,其它属性使用的是系统的默认值。同时大家可以注意到AppliesTo的属性为空值,该属性值表明该密码策略对象被应用到了哪些对象。接下来我们就用Set-ADFineGrainedPasswordPolicy对其它属性值进行修改。具体代码如下:

Get-ADFineGrainedPasswordPolicy -Identity ITAdminsPSO `
| Set-ADFineGrainedPasswordPolicy -LockoutDuration 0.00:30:00 `
-LockoutObservationWindow 0.00:30:00 -LockoutThreshold 5 `
-MinPasswordAge 0 -MaxPasswordAge 30.00:00:00 -Verbose

运行结果如下:

07

最后我们来看一下如何删除精细化的密码策略对象。方法很简单,还是先使用Get-ADFineGrainedPasswordPolicy得到对象然后通过管道传递给Remove-ADFineGrainedPasswordPolicy,并确认删除操作。相信大家都已经想到下面的代码了:

Get-ADFineGrainedPasswordPolicy -Identity ITAdminsPSO `
| Remove-ADFineGrainedPasswordPolicy

运行结果如下:

08

接下来为了稍后的讲解需要,我将创建名为ITAdmins01PSO和ITAdmins02PSO的精细化的密码策略。这两个策略的区别在于密码的长度及Precedence参数的值。创建完成之后,我们可以来看一下对象有没有成功创建:

09

最后要提醒的一点是Get-ADFineGrainedPasswordPolicy支持Filter参数,我们可以使用该参数来获得多个对象。该参数相信通过之前的介绍,各位应该很熟悉了,这里就不再赘述了。

到此为止,我们仅仅完成了密码策略对象的创建。接下来我们需要使用名词部分是ADFineGrainedPasswordPolicySubject的cmdlets将密码策略对象应用到具体对象。

  • ADFineGrainedPasswordPolicySubject

与ADFineGrainedPasswordPolicySubject配合的动词有Add,Get和Remove。我们首先将ITAdmins01PSO应用到名为IT全局安全组,使用的代码如下:

Add-ADFineGrainedPasswordPolicySubject -Identity ITAdmins01PSO -Subjects IT -Verbose

执行效果如下:

10

当然除了安全组之外,还能密码策略对象还能应用到具体用户。

接下来我们可以用Get-ADFineGrainedPasswordPolicySubject来查看密码策略对象被应用到了哪些对象,具体代码如下:

Get-ADFineGrainedPasswordPolicySubject -Identity ITAdmins01PSO

运行效果如下:

11

接下来我们使用Remove-ADFineGrainedPasswordPolicySubject来删除密码策略对象与具体对象之间的连接,具体命令如下:

Remove-ADFineGrainedPasswordPolicySubject -Identity ITAdmins01PSO -Subjects IT

命令的执行效果如下:

12

最后为了能说明Get-ADUserResultantPasswordPolicy cmdlet。我将把ITAdmins01PSO及ITAdmins02PSO分别连接到名为IT的全局安全组及admin001的用户对象上,同时在IT安全组内还有名为admin002的用户对象。整个执行过程如下:

13

  • ADUserResultantPasswordPolicy

终于到了检验我们设置的精细化密码策略有没有设置成功的时刻了,这里将通过Get-ADUserResultantPasswordPolicy cmdlet来进行验证。验证过程如下图所示:

14

从结果中我们可以看到ITAdmins02PSO被正确应用到了admin001对象上,而admin002因为是IT组的成员,因此被应用到了ITAdmins01PSO对象上。接下来我们需要验证多个密码策略对象被应用到同一个对象时的情况。整个验证过程如下:

15

首先我们删除应用到全局安全组的IT的密码策略对象,然后将ITAdmins01PSO应用到用户admin001,这里需要注意的是ITAdmins01PSO的优先级是100。然后我们再将ITAdmins02PSO应用到用户admin001,而ITAdmins02PSO的优先级是200,最后我们执行Get-ADUserResultantPasswordPolicy cmdlet确认admin001到底应用了哪个密码策略对象。因为之前我在新建密码策略对象时指定了Precedence参数,所以结果很明显,admin001应用到的是数值越小优先级越高的ITAdmins01PSO。

本次关于密码策略的介绍就到此结束了,敬请期待下次的介绍。

PowerShell V2介绍(27) - Managed Service Accounts

大家好,今天要为大家介绍的是在Windows 7及Windows Server 2008 R2中新增加的一种用户账号类型:Managed Service Account。由于目前没有提供图形界面来管理Managed Service Accounts,因此要管理这种新的账号类型,我们需要使用Windows PowerShell的AD模块。接下来就来确认与Managed Service Accounts有关的cmdlets,具体命令如下:

Get-Command *ServiceAccount*

从返回的结果中,我们可以看到共有10个cmdlets与Managed Service Accounts有关:

01

在具体操作之前需要向各位确认下我的测试环境。在测试环境中,域控制器的操作系统均为Windows Server 2008 R2,域和林的功能级也均为Windows Server 2008 R2。当你的域控制器是Windows Server 2003或Windows Server 2008时,请参阅《Service Accounts Step-by-Step Guide》的“Requirements for using managed service accounts and virtual accounts”一节中的相关内容。

接下来我们就来看看如何使用Managed Service Accounts。首先我们要做的当然是新建一个Managed Service Account,用到的命令是New-ADServiceAccount。具体命令如下:

New-ADServiceAccount -Name ITAppPool -SamAccountName ITAppPool `
-Description "Account Application Pool"

在测试环境中我安装了一台IIS服务器,接下来我们将为这台IIS服务器上的应用程序池IT来配置使用Managed Service Account。在以后的使用中,可能大家会使用相当数量的Managed Service Accounts,因此建议大家使用Description来区别用于不同系统的账号。下面我们就使用Get-ADServiceAccout来查看刚才新建的账号。具体命令如下:

Get-ADServiceAccount -Identity ITAppPool

命令的执行效果如下:

02%2057D7E823.png" width=580 height=173>

接下来大家可能会遇到需要修改账号属性的情况。和之前修改用户账号属性一样,我们只需要使用Set-ADServiceAccount便能完成。比如我们可以使用以下命令来修改之前所建账号的描述属性:

Set-ADServiceAccount -Identity ITAppPool -Description "Account for IT Application Pool"

由于Set-ADServiceAccount自带Description参数,使得我们能很容易的修改描述属性。但是在实际工作中,我们可能需要修改账号的其它属性,比如Location。当然看过之前相关介绍的朋友可能已经想到了Set-ADServiceAccount肯定提供了Add参数来让我们使用哈希表来修改其它属性值。因此,如果需要修改其它属性,我们可以使用类似以下形式的命令:

Set-ADServiceAccount -Identity ITAppPool -Add @{location="Shanghai"}

最后我们再次使用Get-ADServiceAccount来查看所做的修改有没有生效,具体命令如下:

Get-ADServiceAccount -Identity ITAppPool -Properties Description,Location

由于Get-ADServiceAccount默认返回的结果中不包含Description和Location属性,因此我们需要使用Properties参数来指定需要返回的属性值。这三条命令的执行过程如下图所示:

03

最后我们再来看一下如何删除Managed Service Account。方法很简单,使用Remove-ADServiceAccount即可,具体命令及执行效果如下图所示:

04

通过以上介绍我们可以大致了解如何创建和管理Managed Service Accounts。但这只是使用Managed Service Accounts的一个环节,接下来我们需要在使用Managed Service Account的成员服务器上安装相关账号。

为了在成员服务器上安装Managed Service Account,必须要要在成员服务器上安装.NET Framework 3.5x 及 PowerShell AD模块。我们可以使用服务器管理器来安装这两项功能,这里就不再赘述了。安装完成之后,我们便可以使用Install-ADServiceAccount来在成员服务器上安装Managed Service Account。具体命令如下:

Get-ADServiceAccount -Filter "(Name -eq 'ITAppPool')" | Install-ADServiceAccount

我们可以使用Get-ADServiceAccount来确认账号是否安装成功,这里需要注意HostComputers属性在安装前后发生的变化:

05

接下来我们就可以为相应的应用程序池配置Managed Service Account。注意设置账号时在最后需要加上$。

06

接下来我们可以重启下应用程序池来确认应用程序池能否使用Managed Service Account来启动。

最后如果我们不再需要使用Managed Service Account的话,可以使用Uninstall-ADServiceAccount来从成员服务器上删除相关账号。当然删除之前你需要先修改使用Managed Service Account的应用程序。然后再使用Uninstall-ADServiceAccount来卸载账号。

如果我们需要重置Managed Service Account的密码的话,可以在安装Managed Service Account的计算机上执行Reset-ADServiceAccountPassword即可。

如果我们不方便或者无法在成员服务器上登录,那也可以在域控制器或其它服务器上使用剩下的三个cmdlets来完成相应的Managed Service Accounts的安装工作。他们的名词部分都是ADComputerServiceAccount。我们可以先用Get-ADComputerServiceAccount来查看和成员服务器绑定的Managed Service Account。具体命令如下:

Get-ADComputerServiceAccount -Identity TestServer

命令的执行结果如下:

07

我们可以通过DistinguishedName来得到绑定到这台计算机的Managed Service Account。接下来在成员服务器上删除Managed Service Account后,再来看看能不能在域控制器上为成员服务器添加Managed Service Account。具体命令如下:

Add-ADComputerServiceAccount -Identity TestServer -ServiceAccount ITAppPool

最后如果我们可以使用Remove-ADComputerServiceAccount来从成员服务器上删除Managed Service Account。命令如下:

Remove-ADComputerServiceAccount -Identity TestServer -ServiceAccount ITAppPool

执行效果如下:

08

本次关于如何使用PowerShell AD Module来管理Managed Service Account的介绍就到此结束了,敬请期待下次关于密码策略的介绍。

PowerShell V2介绍(26) - 管理活动目录林和域(下)

今天要接着为大家介绍管理活动目录林和域所需的cmdlets,首先来看看和域控制器相关的两个cmdlets,Get-ADDomainController和Move-ADDirectoryServer。

  • Get-ADDomainController

从cmdlet名称上看Get-ADDomainController 很显然是用来获得域控制器的相关信息,下图就是该cmdlet的一些摘要信息。

01

我们可以直接使用语法一来获得一台或多台域控制器的信息。下面我将使用该cmdlet来获得名为DC01的域控制器信息,具体命令如下:

Get-ADDomainController -Identity DC01

命令的运行结果如下:

02

当然使用语法一的条件是,你对命令所运行的域环境很了解,知道域控制器的名称。当你希望编写具有普适性的PowerShell脚本时则不适合使用语法一。为了解决这个问题,我们必须使用语法二中提供的参数。语法二中的参数有:

参数名

作用

AvoidSelf

在查询结果中不包含运行命令的这台域控制器,如果你通过一台专用的管理机器连接到AD DS,则不需要指定此参数

DomainName

域名

ForceDiscover

指定该参数后,可以在运行命令前清空缓存,避免返回缓存的域控制器信息

MinimumDirectoryServiceVersion

指定该参数后,可以通过操作系统版本来筛选返回的域控制器

NextClosestSite

指定该参数后,当运行命令的计算机所在的站点中查询不到相关DC时,PowerShell将从下一个最近的站点来查询信息

Service

通过设置该参数的值,可以使得Get-ADDomainController返回具有不同服务角色的域控制器。参数值的范围是:PrimaryDC,GlobalCatalog,KDC,TimeService,ReliableTimeService及ADWS

SiteName

可以通过设置SiteName及其参数值,来查找特定站点中的域控制器

Writable

可以指定Writable参数来确定是否仅返回可写域控制器还是只读域控制器

这里需要注意的是,以上参数必须和Discover参数配合使用,大家也可以看到在语法说明中Discover是必要参数而非可选参数。下面我们就来看看两个使用不同参数后Get-ADDomainController返回的不同结果:

得到除了当前域控制器之外的其他域控制器对象

 03

获得当前域中的一个可用域控制器

04

如果通过设置以上参数还不能得到令你满意的结果的话,那么可以使用语法三来实现你想要的结果。具体涉及到的参数是Filter。使用方法与之前查询用户时的方法相同,下面就来看一个例子:

Get-ADDomainController -Filter {Name -like 'DC*'} 

05

  • Move-ADDirectoryServer

说完Get-ADDomainController之后,再来看看Move-ADDirectoryServer。Move-ADDirectoryServer的作用就是在站点之间移动域控制器。我们可以结合之前的Get-ADDomainController来找到要移动的域控制器,然后将得到的对象通过管道传递给Move-ADDirectoryServer来完成移动。下面就来看看具体的命令:

Get-ADDomainController -Filter {IsReadOnly -eq $true} | Move-ADDirectoryServer -Site "Beijing" 

命令的执行效果如下:

06

  • Set-ADDomainMode和Set-ADForestMode

在讲完和域控制器相关的cmdlets后,再来看看设置域功能级及林功能级的cmdlets: Set-ADDomainMode和Set-ADForestMode。我们只需为Set-ADDomainMode和SetADForestMode分别指定DomainMode及ForestMode参数来指定具体要设置的功能级。DomainMode的参数值有:Windows2000Domain,Windows2003InterimDomain,Windows2003Domain,Windows2008Domain,Windows2008R2Domain。而ForestMode的参数值有:Windows2000Forest,Windows2003InterimForest,Windows2003Forest,Windows2008Forest,Windows2008R2Forest,UnknownForest。

接下来可能大家会认为这两个cmdlet可能是所有cmdlets中使用最简单而且使用频率最少的两个cmdlet。因为域功能级和林功能级在提升后便不能回滚了,所以基本上在真实环境中只使用一次……

当然域和林功能级不能回滚的印象来自我们在Windows Server 2003和Windows Server 2008下的管理经验,实际上到了Windows Server 2008 R2时代,有一种特殊情况可以使得我们回滚域功能级:

将域功能级别设置为某个值之后,就不能回滚或降低域功能级别,但有一种情况例外:当您将域功能级别提升到 Windows Server 2008 R2 且林功能级别为 Windows Server 2008 或更低时,可以选择将域功能级别回滚到 Windows Server 2008。只能将域功能级别从 Windows Server 2008 R2 降到 Windows Server 2008。例如,如果将域功能级别设置为 Windows Server 2008 R2,则无法将其回滚到 Windows Server 2003。

下面我们就用这个特例来作为Set-ADDomainMode和Set-ADForestMode的示例,具体操作过程如下:

1. 确认当前的域功能级和林功能级

07

2. 将域功能级提升到Windows2008R2Domain,林功能级提升到Windows2008Forest。当然功能级提升是一个关键操作,因此PowerShell会给出提示:

 08

3. 接下来,我们就来进行还原操作,当然只能将域功能级从Windows Server 2008 R2降级到Windows Server 2008,而不能降级到Windows Server 2003,降级到2003时会出现失败提示。下面来看下执行过程:

09

10

  • ADDomainControllerPasswordReplicationPolicy和ADDomainControllerPasswordReplicationPolicyUsage

接下来我们来看一下和密码复制策略有关的cmdlets,他们的名词部分分别是ADDomainControllerPasswordReplicationPolicy和ADDomainControllerPasswordReplicationPolicyUsage,共计四个cmdlets。

虽然这些cmdlets的名称部分看上去很复杂,但实际上对应的就是只读域控制器属性中的密码复制策略及其高级按钮中的相关设置。

11 12

下面我们就首先使用Get-ADDomainControllerPasswordReplicationPolicy得到密码复制策略中的应用列表和拒绝列表。具体命令如下:

Get-ADDomainControllerPasswordReplicationPolicy -Identity NWTrader-RODC01 -Allowed | FT Name
Get-ADDomainControllerPasswordReplicationPolicy -Identity NWTrader-RODC01 -Denied | FT Name

这里Identity的参数值代表只读域控制器的sAMAccountName,在我的测试环境中就是NWTrader-RODC01,而Allowed及Denied参数就表示是得到密码复制策略的应用列表和拒绝列表。不过这两个参数不能在同一条命令中使用,因为他们分别属于不同的语法,下面就来看看运行的结果:

13

因为NWTrader-RODC01位于Beijing站点,因此我们希望允许BJUsers用户组的成员的密码复制到只读域控制器上。那么可以使用以下命令来完成这个任务:

Add-ADDomainControllerPasswordReplicationPolicy -Identity NWTrader-RODC01 -AllowedList BJUsers -Verbose 

命令的执行效果如下:

14

这里需要注意的是Identity参数和AllowedList参数是不支持管道输入的,因此我们需要使用sAMAccountName来作为参数值。接下来我们在用之前的命令来验证下刚才的添加命令有没有执行成功:

15

如果之后我们想要将BJUsers组从允许列表中删除的话,只需将之前的Add-ADDomainControllerPasswordReplicationPolicy替换成Remove-ADDomainControllerPasswordReplicationPolicy即可。

16

当然这里也可以使用组嵌套的方法来实现,将需要允许或拒绝的组添加到默认的Allowed/Denied RODC Password Replication Group这两个组即可,这就涉及到之前介绍的如何使用cmdlets来管理组成员的方法了,今天就不再多做介绍了。

  • ADDomainControllerPasswordReplicationPolicyUsage

最后我们再来看一下Get-ADDomainControllerPasswordReplicationPolicyUsage。该cmdlet的作用是获得通过只读域控制器进行身份验证或具有存储在该 RODC 上的密码的用户或计算机账户。

该cmdlet由于只是用来查看信息,因此使用起来很简单,主要的参数有指定使用哪台只读域控制器的参数Identity,搜索已通过只读域控制器身份验证的参数AuthenticatedAccounts,以及搜索密码已储存在只读域控制器上的参数RevealedAccounts。下面就来看两个例子:

Get-ADDomainControllerPasswordReplicationPolicyUsage `
-Identity NWtrader-RODC01 -AuthenticatedAccounts | FT Name,ObjectClass
Get-ADDomainControllerPasswordReplicationPolicyUsage `
-Identity NWtrader-DC01 -RevealedAccounts | FT Name,ObjectClass

命令的执行效果如下:

17

本次关于管理活动目录林和域的介绍就到此结束了,敬请期待下次关于Managed Service Accounts的介绍。

 

 

PowerShell V2介绍(25) - 管理活动目录林和域(上)

今天要为大家介绍的是和管理活动目录林和域对象有关的cmdlets。涉及到的名词有ADDomain、ADDomainController、ADDomainControllerPasswordReplicationPolicy、ADDomainControllerPasswordReplicationPolicyUsage、ADDomainMode、ADForest、ADDirectoryServer和ADDirectoryServerOperationMasterRole。我们可以使用以下命令来得到包含这些名词的cmdlets:

Get-Command *ADDomain*,*ADForest*,*ADDirectory* -Module ActiveDirectory | Sort Noun | FT -a

最后的返回结果中包含13个cmdlets:

01

接下来将基于完成具体任务的方式来介绍名词部分是ADDomain及ADForest的cmdlets。

  • 对FSMO主机进行操作

如果我们需要对FSMO主机进行操作则需要使用Get-ADDomain、Set-ADDomain、Get-ADForest及Set-ADForest这四个cmdlets。首先来看看Get-ADDomain能提供给我们一些什么样的信息。

02

大家可以看到Get-ADDomain得到的信息还是很丰富的,比如子域的信息(ChildDomains),域功能级(DomainMode),操作主机(PDCEmulator、RIDMaster)等等。接下来我们来看看Get-ADForest会得到哪些信息:

03

大家可以看到Get-ADForest为我们提供了林范围内的一些信息,接下来我们就来看看如何得到FSMO角色所在的主机。

具体命令如下:

Get-ADDomain | fl PDC*,*Master
Get-ADForest | fl *Master

04

在得到FSMO主机角色之后,相信大家接下来就会很好奇能不能使用PowerShell来转移FSMO角色了。当然从Windows Server 2008 R2开始我们就可以不在使用ntdsutil或者图形界面来转移FSMO角色了。在AD PowerShell 模块中为活动目录管理员准备了Move-ADDirectoryServerOperationMasterRole cmdlet来转移FSMO角色。下面我们就来看下如何使用这个cmdlet。具体命令如下:

Move-ADDirectoryServerOperationMasterRole -Identity dc01 -OperationMasterRole SchemaMaster

执行效果如下,这里我们可以利用之前的命令来确定命令有没有执行成功。

05

这里需要注意的是Identity参数,大家从Get-Forest返回的值来看肯定会认为用dc02.contoso.com代替dc02作为Identity的参数值也是可以的。但实际上这并不可行。原因在于此cmdlet在执行时会从CN=Configuration,dc=contoso,dc=com分区中查找信息,也就是说如果我们想要以DN作为Identity参数的值的话,那么需要使用类似以下形式的DN:CN=DC01,CN=Servers,CN=Shanghai,CN=Sites,CN=Configuration,DC=contoso,DC=com

  • 修改单个用户将计算机加入域的上限数量

相信很多朋友都知道,默认情况下域中的普通用户可以将10台计算机加入到域,超过这个上限之后便无法添加了。根据KB251335的说明,我们可以通过预先创建用户的计算机账号,为用户授予计算机账号所在OU的添加/删除计算机对象权限,以及修改ms-DS-MachineAccountQuota这个属性来绕过这个限制。接下来就来看看如何使用相关cmdlets来修改ms-DS-MachineAccountQuota这个属性。

根据“获得对象,然后对其进行操作”的PowerShell AD Module的使用原则,首先要确定如何使用cmdlet来获得我们所需的对象。由于ms-DS-MachineAccountQuota这个属性是域对象的一个属性,因此可以使用Get-ADDomain来得到域对象。接下来我们自然而然地会想到将得到的对象通过管道传递给Set-ADDomain来修改相关的属性值。默认情况下,Set-ADDomain并不直接提供与属性相对应的参数来修改属性值,因此我们还是和之前修改用户对象的属性一样,需要使用哈希表来表示需要进行修改的具体属性值。命令如下:

Get-ADDomain | Set-ADDomain -Replace @{"ms-ds-MachineAccountQuota"=1}

命令执行完之后,我们可以通过ADUC中的属性编辑器或者Sysinternals工具包中的ADExplorer来查看属性有没有修改成功:

 06

  • 修改林对象的UPN后缀

接下来我们来看看如何修改林的UPN。对于一部分朋友来说,在平时的工作中我们可能不会太区分用户的用户登录名和用户登录名(Windows 2000以前版本),也就是常见的someone@example.com及Example\someone这两种格式,或许会认为这两种格式差别不大。当然在一个简单的域环境中这样认为是不错的。不过假设你的林中有了父子域并添加相应的UPN后缀之后,可以使得我们在父域创建账号时能方便的选择子域的UPN后缀,使得该账号能在子域中登录。接下来我们就来看看如何使用相关的cmdlets来添加UPN后缀。

首先需要明确的一点是修改UPN后缀是针对林的操作,换言之我们要得到的是林对象,那么大家很快就会想到使用Get-ADForest命令。接下来为了完成修改操作,我们自然而然地会想到使用Set-ADForest命令。然后要确认的就是Set-ADForest是不是存在之前Set-ADUser中类似的Add,Replace,Remove之类的参数,然后使用哈希表对象来修改属性值,还是直接有对应的参数来进行修改。这里比较庆幸的是Set-ADForest有专用的参数UPNSuffixes来修改UPN后缀名。不过UPNSuffixes参数的属性值类型也是哈希表,但是和我们之前所看到Add,Replace,Remove参数中使用的“属性名=值”形式的哈希表所不同的是,UPNSuffixes所使用的哈希表的形式是“动词=UPN后缀名”。

光这样说可能大家不是很理解,接下来我们就来看下具体示例。在我的测试环境中有contoso.com及asia.contoso.com两个域,为父子关系,接下来我们就用命令在父域中添加子域的UPN后缀名。具体命令如下:

Get-ADForest | Set-ADForest -UPNSuffixes @{add="asia.contoso.com"} -Verbose

命令的执行效果如下:

07

接下来,我们就可以在新建用户时指定用户的UPN后缀,或者使用图形界面修改现有用户的UPN后缀。这里为了使大家看的更清楚,下面将使用图形界面来确认修改有没有成功:

08

可以看到,修改是成功的。接下来自然有朋友会问,如何用命令把@asia.contoso.com删除呢?方法很简单,还是刚才的代码,我们只需将add替换成remove即可。如果要添加多个UPN后缀的话则可以使用 , 隔开属性值,最后的UPNSuffixes参数值类似以下形式@{add="asia.contoso.com","euro.contoso.com"}

本次关于如何使用cmdlets来管理活动目录林和域的上半部分介绍就到此结束了,敬请期待下半部分的介绍。

PS,虽然前几天ITECN无法访问,不过这次回来之后,ITECN所在的服务器已经升级到Windows Server 2008 R2了哦,还在犹豫是不是要马上购买Windows Server 2008 R2的朋友还是马上决定购买吧。ITECN都升级了,相信你没有理由不升吧? ;-)

PowerShell V2介绍(24) - ADOrganizationalUnit

通过之前几次的介绍,相信大家已经大体了解了如何使用Windows PowerShell ADModule来管理用户和组。今天要为大家介绍的是和组织单位管理相关的cmdlets。和组织单位管理的相关的名词只有一个ADOrganizationalUnit,而对应的动词也是各位已经很熟悉的四个New、Get,Set及Remove。下面还是按照对象生命周期的顺序来介绍。

  • New-ADOrganizationalUnit

首先要为大家介绍的是创建组织单位的New-ADOrganizationalUnit。和之前几次介绍类似,先来看看它的语法。

image

和New-ADUser那一堆用户属性参数相比,New-ADOrganizationalUnit可是简洁了很多,除了Name,Displayname,Description以及ManagedBy等一些和组织单位相关的常规参数外,相信大家也注意到了我用红框圈出来的参数ProtectedFromAccidentalDeletion。想必用过Windows Server 2008活动目录的朋友都了解在新建OU时会有一项名为“防止对象被意外删除”的选项且默认是勾选的,这项选项主要防止管理员不当的删除操作引起的一些麻烦。当然这么贴心的设计在Windows Server 2008 R2中肯定是被保留的。而New-ADOrganizationalUnit则通过参数ProtectedFromAccidentalDeletion实现这一需求。当然用户对象和组对象也是可以设置防止意外删除的选项的,不过在相关的cmdlet中没有对应到具体的参数,至于如何使用cmdlet来对用户和组启用这个设置,这里我就先卖个关子。下面我们就先来看看如使用New-ADOrganizationalUnit来创建OU,具体命令如下:

New-ADOrganizationalUnit -Path "OU=Shanghai,OU=NWTrader,dc=NWTrader,dc=com" `
-Name HR -DisplayName HR -Country CN -City Shanghai -Verbose

命令的执行效果如下:

image

这里需要注意的是Country的属性值需要使用ISO 3166规范来指定,如果你不想再开个浏览器去查阅文献的话,最简单的方法就是再某一个OU上设置下国家属性,然后在属性编辑器中查看对应的Country对应的属性值,一般我们只需记住几个常用的即可。

  • Get-ADOrganizationalUnit和Set-ADOrganizationalUnit

在创建完OU后,接下来的任务就是对OU进行管理。首先在之前新建OU的时候代码中没有指定OU的管理者,接下来我们就来指定OU的管理者。具体代码如下:

Get-ADOrganizationalUnit -Filter {Name -eq 'hr'} | Set-ADOrganizationalUnit `
-ManagedBy (Get-ADUser -Filter {sAMAccountName -eq 'anna'})–Verbose

执行效果如下:

image

和Get-ADUser anna能直接得到用户对象不同,Get-ADOrganizationalUnit hr是没办法得到OU对象的,因此还是和之前一样需要使用Filter参数来设置查询条件找到具体的OU对象,在刚才的代码中查询条件设置为查找Name为HR的OU,并且使用eq操作符做精确匹配。因此我们可以通过这个命令得到HR这个组织单位对象,接下来就利用管道将对象传递给Set-ADOrganizationalUnit。而管理者属性对应的参数是ManagedBy,对象类型是ADPrincipal,因此需要使用Get-ADUser或者Get-ADGroup来得到用户或组对象,这里将指定用户Anna作为HR的管理者,然后使用()更改命令执行的优先级并使之成为一个对象,否则命令运行时将出错:

image

接下来我们来看看如何批量设置OU的管理者。比如NWTrader集团在北京成立了新的分公司,新的分公司下设置了Sales,HR,Financial,也就意味着这几个OU需要设置管理者。下面我们就来看看如何操作。先来看看具体代码:

$managers = Import-Csv "c:\powershell\ous.csv" 
foreach ($manager in $managers)
{
$OUName = $manager.ouname
$OUManager = Get-ADUser $manager.oumanager
Get-ADOrganizationalUnit `
-Filter {Name -eq $OUName} `
-SearchBase "OU=Beijing,OU=NWTrader,dc=nwtrader,dc=com" `
| Set-ADOrganizationalUnit -ManagedBy $OUmanager -Verbose
}

具体的执行效果如下:

image

而ous.csv中的内容是:

OUName,OUManager 
HR,BJUser001
Sales,BJUser002
Financial,BJUser005

首先代码中使用Import-Csv将ous.csv中的内容存放到$managers变量中。接着使用foreach来遍历$managers中的对象。在foreach循环中则将OU的名称和管理者分别赋值给$OUName及$OUManager供后续命令使用。接下来就是利用之前的Get-ADOrganizationalUnit和Set-ADOrganizationalUnit来设置OU的管理者。为了避免命令在一行中过长,因此使用 ` 作为续行符。而导致命令过长的原因是因为加入了SearchBase及其参数。参数的作用就是限制Get-ADOrganizationalUnit的搜索范围,因为其它分公司的OU结构和Beijing分公司的OU结构类似,也存在Sales,HR,Financial等OU,因此需要使用SearchBase参数来限制。

接着这个例子,我们再来看一下如何清除OU的管理者属性,这里将使用Set-ADOrganizationalUnit的Clear参数,只要将上述代码中的
Set-ADOrganizationalUnit -ManagedBy $OUmanager -Verbose
替换为
Set-ADOrganizationalUnit -Clear ManagedBy -Verbose
即可。其中Clear的参数值是具体的属性名。

  • Remove-ADOrganizationalUnit

最后再来看看Remove-ADOrganizationalUnit。相信大家看过前几次的介绍之后肯定会说Remove-ADOrganizationalUnit用起来还不简单么?用Get-ADOrganizationalUnit得到OU对象然后再用管道传递给Remove-ADOrganizationalUnit,然后再确认是否删除不就结了?那我们看看下面的代码是不是能成功执行:

 image

“拒绝访问”?可能这时很多朋友马上会一愣,然后马上反应过来,原来是“防止对象被意外删除”选项。因此我们需要在删除之前,取消掉这个选项。修改后的命令如下:

Get-ADOrganizationalUnit -Filter {Name -eq 'Test'} | Set-ADOrganizationalUnit `
-ProtectedFromAccidentalDeletion $false -PassThru | Remove-ADOrganizationalUnit

这里需要注意Set-ADOrganizationalUnit添加了PassThru了参数,目的是为了向后续的管道传递修改后的后的OU对象,默认情况下Set-ADOrganizationalUnit 是不会返回修改后的对象的,因此必须指定PassThru参数使得Remove-ADOrganizationalUnit能得到操作对象。

本次关于ADOrganizationalUnit的cmdlets介绍就到此结束了,敬请期待下次的介绍。

PowerShell V2介绍(23) - 活动目录组对象的管理(下)

大家好,今天要为大家介绍的是名词部分为ADAccountAuthorizationGroupship及ADPrincipalGroupMembership的cmdlets,共四个cmdlets:

image

首先来看看Get-ADAccountAuthorizationGroup。该cmdlet的作用是获得指定用户所属的tokenGroup的信息。该cmdlet的使用方法很简单,比如我们可以执行以下命令:

Get-ADAccountAuthorizationGroup -Identity BJUser001 | FT Name,Group*

命令的执行效果如下图所示:

image

大家可能注意到了我之前使用了tokenGroup这个词,对很多朋友来说这个词可能比较陌生,简单来说的话tokenGroup是指包含用户所属的所有安全组的SID的一个集合。它不但包含了隶属于选项卡中的安全组,同时也包含了一些特殊的安全组,比如“Authenticated Users”,“Everyone”以及MIC信息。上面例子中的BJUser001只是一个普通的域用户,下面我们来看看默认域管理员的权限:

image

由于测试域环境中安装了Exchange,因此会多出一些和Exchange有关的安全组,当然大家可以看到最后的MIC信息说明默认的Administrator具有“High Mandatory Level”。由于Get-ADAccountAuthorizationGroup提取的是tokenGroup的的信息,而tokenGroup是一个经过计算得出的值,因此不能直接修改,所以与ADAccountAuthorizationGroup相配的动词只有Get。

说完了Get-ADAccountAuthorizationGroup这个有点特殊的cmdlet,接下来我们就来看看大家更为熟悉的ADPrincipalGroupMembership,也就是用来管理用户隶属于关系的cmdlets。

首先我们要做的当然是得到要管理的对象,使用的命令如下:

Get-ADPrincipalGroupMembership -Identity bjuser001 | ft name,group*

命令的执行效果如下:

image

上面的命令中我们获得了bjuser001这个用户的“隶属于”信息,并使用Format-Table(别名ft)来显示组名,组的类型及组的作用域。图中结果说明,bjuser001这个用户属于Domain Users和BeijingUsers这两个安全组以及BJUsers这个通用通讯组。这里需要注意的是Identity参数不支持通配符,你需要输入一个唯一的账户名来获得对应用户的“隶属于”信息。

那这时显而易见会产生一个问题,我们该如何进行批量操作呢?大家不妨考虑下这个情景,由于NWTrader公司市场策略的调整,将撤销北京分公司,原北京分公司的所有员工都调入上海分公司。这时管理员要做的就是将所有隶属于BeijingUsers这个全局安全组的成员全部加入到ShanghaiUsers这个全局安全组。(这里我们暂且考虑全局安全组,刚才命令执行结果中的Exchange通讯组暂不考虑)。那该如何操作呢?下面先来看看代码:

Get-ADGroupMember –Identity BeijingUsers | `
%{Remove-ADPrincipalGroupMembership -Identity $_ -MemberOf BeijingUsers `
-Confirm:$False -Verbose;Add-ADPrincipalGroupMembership -Identity $_ -MemberOf `
ShanghaiUsers -Verbose}

命令的执行效果如下:

image

在以上代码中,我们首先使用Get-ADGroupMember得到北京分公司的用户账号,然后将得到的用户对象通过管道进行传递。这里我直接使用Get-ADGroupMember来得到BeijingUsers组里的成员,也就是北京分公司的用户。当然,在我的实验环境中北京分公司的每个账号的sAMAccountName属性值都以bj打头,因此也可以很方便的使用Get-ADUser来获得相关用户列表。在真实环境中可能每个用户账号的sAMAccountName的属性值没有规律可循,因此我们可能需要使用其它的搜索条件,比如Company属性,此时我们需要将Get-ADUser的 Filter参数值设置成 {Company -eq "北京分公司"}。以上三种得到用户的方法,在实验环境得到的用户对象都是一致的,而在实际环境中我们可以根据情况进行选择。总之,无论如何我们都要想尽办法来得到用户对象,否则就无法进行下一步操作。

接下来我们来看看foreach循环中的代码。正如之前所言,Remove-ADPrincipalGroupMembership和Add-ADPrincipalGroupMembership的Identity参数需要指定一个确定的用户对象,因此我们需要使用foreah循环来遍历通过管道传递过来的每一个用户。而在foreach循环中,首先使用Remove-ADPrincipalGroupMembership将用户从BeijingUsers组中删除,而其中的Identity参数的值是一个用户对象,因为通过用户是通过管道传递的,因此可以使用$_代替。MemberOf参数的值是对应的组的名称。由于Remove操作默认需要用户确认,因此在批量操作时,我们可以通过设置Confirm的参数为$false来关闭确认提示。而Add-ADPrincipalGroupMembership执行的操作则是添加,Identity和MemberOf的参数的解释和Remove-ADPrincipalGroupMembership中的参数是一致的。

本次关于名词部分为ADAccountAuthorizationGroupship及ADPrincipalGroupMembership 的cmdlets的介绍就到此结束了,从下次介绍开始,我们来看看如何使用PowerShell AD模块来管理组织单元,敬请期待。

PowerShell V2介绍(22) - 活动目录组对象的管理(上)

大家好,今天要和大家分享的是如何使用PowerShell V2 AD模块中与组管理相关的cmdlets,共分上下两篇,今天主要介绍的是名词部分是ADGroup及ADGroupMember的cmdlets。共7条命令,如图所示:

image 

  • ADGroup

活动目录中组的生存周期和用户账号一样,一般经历新建-管理-删除这三个阶段。接下来我们就看看如何新建一个组。

毫无疑问,新建一个组需要使用的是New-ADGroup cmdlet。在新建过程中我们需要指定组的名称(对应参数Name),显示名(对应参数DisplayName),登录名(对应参数sAMAccountName),组作用域(对应参数GroupScope,对应参数值是DomainLocal,Global,Universal),组类型(对应参数GroupCategory,对应参数值是Security或Distribution)。如果需要指定组所在OU则需要使用参数Path,而需要添加组的描述信息则可以使用Description参数。如果我们需要在"OU=Test,OU=NWTrader,DC=NWTrader,DC=Com"的OU下建立一个名为Test描述信息也为Test的全局安全组,那么可以使用以下命令:

New-ADGroup -Name Test -SamAccountName Test -Description Test -GroupScope Global -GroupCategory Security -Path "OU=Test,OU=NWTrader,DC=NWTrader,DC=Com"

是不是很简单?同样的该命令执行完成后不会有任何提示信息,如果需要相关执行过程,则可以在命令后加上Verbose参数。下面是命令的执行截图:

image

接下来我们来看看如何使用Get-ADGroup和Set-ADGroup来修改组的相关属性。首先需要了解的是Get-ADGroup的语法:

image

同Get-ADUser一样,Get-ADGroup也有三种语法,两种使用语法使用筛选条件,一种直接得到单个的组对象。要得到多个组对象,大家可以看到之前的Get-ADUser的例子,关键还是在于如何指定Filter参数,这里就不在赘述,下面我将使用Get-ADGroup直接得到一个名为Test01的组对象。

Get-ADGroup Test01,如果没有通过管道传递对象的话,PowerShell将显示和该组有关的一些属性:

image

这里需要注意虽然我没有显示指定任何参数,但按照参数的位置,”Test01”对应的是Identity的参数。由此引出的一个小问题是Identity参数的参数值可以是哪些类型。根据帮助文件提供的信息,Identity的参数值可以是组的DN、GUID,SID和sAMAccountName。通过刚才的截图我们不难发现sAMAccountName是最简单,当然这还取决于具体生产环境中的组的命名规则。

接下来我们就来看看如何使用Set-ADGroup来修改组的一些属性。和Set-ADUser相比,Set-ADGroup默认通过参数修改的属性是比较少的。

image%202A782043.png" width=558 height=311>

这里我们一般会修改的可能就是新建时指定的组的名称,组的作用域,组的类型,因此这些参数包含在了常用参数中。如果我们需要修改额外的属性,则和修改用户一样,需要利用到哈希表。比如我们需要修改相关组属性的注释属性。

image

首先需要知道的就是图形界面中注释对应的是哪个具体的属性名称。好在从Windows Server 2008开始在ADUC的对象属性选项卡里多了属性编辑器这个选项卡,使得我们能比较容易的定位需要修改的属性,而不用像Windows Server 2003时代那样打开adsiedit.msc。

image

通过修改前后的属性值对比,我们可以发现注释对应的属性名称是info,因此,使用Set-ADGroup来修改就变得轻而易举了。具体命令如下:

Get-ADGroup Test01 | Set-ADGroup -Add @{info = "Test01"}

当然注释信息可能随着时间的推移会发生变化,内容也会有所增加,在图形界面中的注释是支持多行的,而在对象编辑器中的info则看上去只支持单行,那么,如何使用Set-ADGroup来写入多行注释内容呢?下面就来看看代码:

Get-ADGroup Test01 | Set-ADGroup -Replace @{info = "Test01`r`nBlah`r`nBlah"} 

这里我们使用了PowerShell中的特殊字符`r和`n,其中`r代表的是回车,`n代表的是换行,类似于VBScript中的vbCrlf。最终效果如下:

image

最后来看一下Remove-ADGroup,同所有动词部分是Remove的cmdlet一样,我们既可以使用管道从Get-ADGroup得到相应的组对象,又可以直接为Remove-ADGroup指定组名来删除相应的组。接下我将使用前一种方法来删除所有以Test打头的测试用组,具体命令如下:

Get-ADGroup -Filter {sAMAccountName -Like "Test*"} | Remove-ADGroup -Verbose

结果如下:

image%204741D50B.png" width=558 height=187>

这里出现确认提示也没什么好惊讶的,因为Remove是属于管理中的高危操作,当然需要三思而后行。

  • ADGroupMember

接下来让我们来看看如何使用名词部分为ADGroupMember 的cmdlets来管理组成员。管理组成员无非涉及到三个操作,添加组成员,得到组成员,以及删除组成员,因此对应的动词分别是Add、Get和Remove。下面我们从比较简单的添加操作说起。

比如NWTrader公司在北京开设了办事处,共有五名成员,现在管理员需要将这五名成员加入到名为BeijingUsers的全局安全组中,那该如何使用Add-ADGroupMember操作呢?先来看看最终的代码:

Add-ADGroupMember -Identity BeijingUsers -Members (Get-ADUser -Filter {sAMAccountName -like "bj*"}) -Verbose

执行效果如下:

image

Add-ADGroupMember cmdlet的使用其实很简单,我们只需要指定的组名 BeijingUsers,以及要添加的组成员即可。当然相信大家都看到了,与以往的操作不同,这次我没有利用管道符来传递对象,而是将Get-ADUser cmdlet得到的用户对象直接作为Members参数的参数值,当然这样操作是没有任何问题的,等一下我们可用Get-ADGroupMember来验证。那么相信很多朋友都会想能不能使用管道来添加组成员呢?答案是可以的,我们只需使用下面的语句即可:

Get-ADUser -Filter {sAMAccountName -like "bj*"} | %{Add-ADGroupMember -Identity BeijingUsers -Members $_ -Verbose}

操作结果如下:

image

这里需要注意的是我们需要对通过管道传递过来的用户数组执行foreach循环来遍历其中的每一个用户对象并对其执行Add-ADGroupMember的操作。当然可能有的朋友会想下面的代码不行么,非要使用foreach循环语句:

Get-ADUser -Filter {sAMAccountName -like "bj*"} | Add-ADGroupMember -Identity BeijingUsers

很遗憾,此时的PowerShell无法识别通过管道传递过来的用户数组对应Add-ADGroupMember cmdlet中哪个参数,同时因为Members参数是必须的,所以PowerShell将给出输入Members参数的提示:

image

说完了如何使用Add-ADGroupMember来添加组成员,接下来就来验证下刚才我们的添加操作是否成功,使用的命令如下:

Get-ADGroupMember BeijingUsers | FT Name 

命令的运行结果如下:

image

可以看到刚才的添加组成员的命令已经成功执行了。接下来我们来讨论下和Get-ADGroupMember cmdlet本身有关的一些有趣的问题情境。

刚才我们已经得到了BeijingUsers组里面有哪些成员,但是在具体的生产环境中,相信很多朋友可能并不满足于此。比如即使是BeijingUsers组里的成员也有可能来自各个不同的部门,有时候我们需要在知道组成员的同时了解相关成员的一些信息,那该如何处理呢?

其实我们只需多次利用管道即可,具体命令如下:

Get-ADGroupMember BeijingUsers | Get-ADUser -Properties Department | FT Name,Department

首先我们使用Get-ADGroupMember来得到组中的用户,然后使用Get-ADUser使得命令执行的结果中包含部门信息,最后我们利用Format-Table来格式化输出。最终命令的执行效果如下:

image

此时可能有朋友会马上想到一个问题,如果遇到组嵌套的情况怎么办?也许有的朋友会立即想到自己写一段代码利用Switch来判断组嵌套的情况,如果是多层组嵌套的话,可能代码的复杂度又要上升了。事实上开发组的牛人们怎么可能不会想到组嵌套的情况,因此他们为我们特地准备了Recursive参数,因此如果存在组嵌套的情况,大家要好好利用Recursive参数,这会为我们节省很多时间,下面就是一个例子:

image

剩下来的任务就是举一反三了,如果我们要增加最后得到的属性,那么只需要在Get-ADUser的Properties参数及最后的FT中添加即可,比如下面的例子就是增加了用户的公司属性:

image

最后我们来看看如何使用Remove-ADGroupMember。和Add-ADGroupMember一样,如果要使用Remove-ADGroupMember来进行批量删除组成员的话则需要使用foreach循环,下面代码的作用就是删除BeijingUsers组中所有成员:

Get-ADGroupMember -Identity BeijingUsers | %{Remove-ADGroupMember -Identity BeijingUsers -Members $_} 

运行效果如下:

image

这时我们会发现,删除多个用户时PowerShell会一直给出确认提示,从谨慎的角度来说这当然是一件好事。但是如果BeijingUsers组中有100个用户,那岂不是要确认100次?此时我们需要为Remove-ADGroupMember添加Confirm参数并设置参数值为false,修改后的命令如下:

Get-ADGroupMember -Identity BeijingUsers | %{Remove-ADGroupMember -Identity BeijingUsers -Members $_ -Confirm:$false}

本次关于名词部分是ADGroup及ADGroupMember的cmdlets的介绍就到此结束了,下次将来介绍ADAccountAuthorizationGroupship及ADPrincipalGroupMembership cmdlets,敬请期待。

PowerShell V2介绍 (21) - ADAccount

今天要为大家介绍的是名词部分包含ADAccount的cmdlets。我们可以使用以下命令来获得这些cmdlets,具体命令如下:

Get-Command *ADAccount,*ADAccountControl,`
*ADAccountExpiration,*ADAccountPassword,`
*ADAccountResultantPasswordReplicationPolicy `
-Module ActiveDirectory | Sort Noun

命令的执行效果如下:

image

名词部分包含ADAccount且与用户帐号相关的cmdlets共计9个,而直接使用*ADAccount*将返回10个cmdlets,多出的一个cmdlet和组相关,因此我们在命令中输入了比较多的名词来限制返回的对象。接下来将为大家按照命令返回的结果一一介绍。首先是名词部分仅包含ADAccount的四个cmdltes。

  • ADAccount

之前我们通过名词确定了首先需要了解的cmdlets,接着我们可以通过动词部分来确定每个cmdlet对应的使用场景。首先从Search-ADAccount说起。因为在本次PowerShell Active Directory Module系列介绍的第一篇中,我给大家总结了使用PowerShell的一个规则,即得到对象然后处理对象。而在今后的活动目录实际管理中,使用Search-ADAccount得到对象,然后通过管道符将对象传递给下面的cmdlet是经常会使用的一种命令执行模式。因此如何使用Search-ADAccount得到需要的对象是今后使用PowerShell进行AD管理的基础。接下来就举三个例子使大家熟悉下Search-ADAccount的使用方法,同时下面的例子也分别涉及到Disable-ADAccount,Enable-ADAccount及Unlock-ADAccount。

从Search-ADAccount的帮助信息中我们可以得知该cmdlet有以下默认参数来对应不同的搜索条件:AccountDisabled、AccountExpired、AccountExpiring、AccountInactive、LockedOut 、PasswordExpired 、PasswordNeverExpires。对应的搜索结果是已禁用的账号、已过期的账号、在指定时间内过期的账号、处于非活动状态的账号、被锁定的账号、密码已经过期的账号及密码永不过期的账号。这里需要注意的是Search-ADAccount没有提供可以通过用户名进行搜索的参数,我们只能用Get-User的Filter参数来得到相关用户。

下面就来看看如何搜索账号已经禁用的账号,命令很简单:

Search-ADAccount -AccountDisabled | Ft Name,ObjectClass

默认情况下Search-ADAccount将使用列表形式返回结果,这里为了能让大家看的比较清楚,所以使用Format-Table来仅显示Name和ObjectClass属性。还需要注意的是如果没有加上ComputersOnly或者UsersOnly参数的话,默认的搜素结果中将包含用户和计算机账户,我们可以根据实际情况来指定ComputersOnly或者UsersOnly参数。

image

接下来,我们使用Enable-ADAccount cmdlet来启用Anna Smith这个用户。命令如下:

Search-ADAccount -AccountDisabled -SearchBase "OU=NWTrader,DC=NWTrader,DC=Com" -SearchScope Subtree | Enable-ADAccount

这里我限制了搜素范围,仅查找NWTrader组织单元下的所有被禁用的帐号,在测试环境中,搜索结果将仅返回Anna这个用户,然后利用管道将Anna这个对象传递给Enable-ADAccount,启用Anna这个用户。

接下来我们来查找已过期的用户账号,并将找到用户的账号禁用。具体命令如下:

Search-ADAccount -AccountExpired -SearchBase "OU=NWTrader,DC=NWTrader,DC=Com" -SearchScope Subtree | Disable-ADAccount -Verbose

这里还需要注意一点,执行以上命令时将不会返回任何信息,也就是我们无法得知哪些用户被禁用了。因此如果有需要的话可以为Disable-ADAccount指定Verbose参数,来查看具体被禁用的账户,下面的执行结果告诉我们名为John Doe和Jean Doe的用户由于账号过期而被禁用:

image

最后我们来看看如何查找由于输错密码而被锁定的账户,然后使用Unlock-ADAccount cmdlet来解锁。具体命令如下:

Search-ADAccount -LockedOut -SearchBase "OU=NWTrader,DC=NWTrader,DC=Com" -SearchScope Subtree | Unlock-ADAccount -Verbose

命令和刚才的差不多,我们只需使用-LockedOut参数便能找到被锁定的账号,然后使用Unlock-ADAccount cmdlet来解锁。命令执行效果如下:

image

  • ADAccountControl

再说完了名词部分是ADAccount的四个cmdlets后,我们再来看看Set-ADAccountControl cmdlet。该cmdlet的参数对应部分ADUC中用户账号下的账户选项卡的账户选项。而像“用户下次登录时需更改密码”,“交互式登录必须使用智能卡”则可以使用Set-ADUser的ChangePasswordAtLogon和SmartcardLogonRequired参数来设置。因此Set-ADAccountControl的使用并不复杂。我们可以使用Search-ADAccount或者Get-ADUser来得到用户对象,然后使用管道符将用户对象传递给Set-ADAccountControl并指定合适的参数即可。

image image

  • ADAccountExpiration

接下来是名词部分是ADAccountExpiration的Set-ADAccountExpiration和Clear-ADAccountExpiration。通常而言在AD用户管理中我们会为诸如实习生或者一些特殊用途帐号设置账户过期属性。在新建用户时可以使用New-ADUser cmdlet的AccountExpirationDate参数来指定账户过期时间,但可能之后原本过期时间是两个月的账户由于工作需要延长一个月的过期时间,此时就是Set-ADAccountExpiration的用武之地了。下面来看一个例子。

比如某公司最近接收了一批实习生,原定他们是在2009/12/31结束实习的,可是由于学校的一些安排使得他们不得不在2009/11/30结束实习。接下来我们可以用Search-ADUser来查找所有在账号过期时间是2009/12/31的用户。命令如下:

Search-ADAccount -AccountExpiring -DateTime "2010/01/01" | ft Name,AccountExpirationDate

这里大家可能会马上注意到我设置的日期是“2010/01/01”,而我们在ADUC里面设置的或者说看到的是2009/12/31,这是怎么回事呢?看了下面的命令的运行结果相信大家就会知道了:

image

请注意AccountExpirationDate的值,如果指定DateTime的值为 “2009/12/31”将搜索不到任何用户,还请大家留意了。这也可以算是对“你所看到的事实不一定是事实”这句话的佐证了。当然咬文嚼字的话,你会发现图形界面那里的标签写着是“在这之后”。

在经历过这个小插曲之后,接下来的事情就简单了,我们只要将用户对象传递给Set-ADAccountExpiration并修改过期日期即可,具体命令如下:

Search-ADAccount -AccountExpiring -DateTime "2010/01/01" | Set-ADAccountExpiration -DateTime "2009/12/01" -Verbose

执行效果如下:

image

而Clear-ADAccountExpiration想必就不用我赘述了,主要是用来清除用户帐号的过期日期,使得用户没有过期限制,我们只需将之前的命令改成以下形式就能清除用户帐号的过期日期:

Search-ADAccount -AccountExpiring -DateTime "2010/01/01" | Clear-ADAccountExpiration -Verbose
  • ADAccountPassword

接下来让我们来看下如何设置用户的密码。这里大家可以仿照之前使用Search-ADAccount的方法来找到修要修改密码的账户,这里就不在多做这方面的演示了。Set-ADAccountPassword中比较常用的参数有NewPassword和Reset,也就是对应我们实际管理工作中的重设用户密码的操作。具体命令如下:

Set-ADAccountPassword anna -Reset -NewPassword (Read-Host -AsSecureString "New Password")

这里需要注意的是NewPassword参数值的类型是SecureString,因此我们使用Read-Host及AsSecureString参数来提示用户输入新的密码。具体命令的执行效果如下:

image

  • ADAccountResultantPasswordReplicationPolicy

最后再来看下Get-ADAccountResultantPasswordReplicationPolicy。从Windows Server 2008开始新增加了只读域控制器,我们可以使用密码复制策略来控制只读域控制器储存的用户和计算机密码。默认情况下只有属于“Allowed RODC Password Replication Group”中的成员才会在只读域控制器上储存密码。而根据活动目录的最佳操作实践,我们会使用组嵌套来进行管理。比如Beijing站点中部署了只读域控制器,然后建立了名为BeijingUsers的用户组,然后将BeijingUsers这个用户组加到“Allowed RODC Password Replication Group”中。但是这样的管理,可能会造成这样的一个困扰,比如有一天我想知道John这个用户的密码是不是在Beijing的只读域控制器上进行了缓存,这时由于多层测组嵌套可能让我们一下子毫无头绪。如果这时有类似文件系统的“有效权限”选项卡,那无疑将解决我们的问题。

当然在微软不可能没有考虑到这个问题,我们可以在ADUC的相应选项卡中添加需要查询的用户来确认其是不是允许在只读域控制器上缓存密码。

image

当然这里通过按钮添加独立的用户显然是比较繁琐的,因此我们可以通过Get-ADAccountResultantPasswordReplicationPolicy来进行批量处理。具体命令如下:

Get-ADUser -Filter {sAMAccountName -like "J*"} | Get-ADAccountResultantPasswordReplicationPolicy -DomainController Nwtrader-RODC01

这里我们使用Get-ADUser得到用户登录名的首字母是J的用户,然后将得到的对象通过管道传递给Get-ADAccountResultantPasswordReplicationPolicy,并在只读域控制器NWTrader-RODC01上查询密码复制策略的结果,结果如下:

image

这时又遇到了一个问题,输出结果中只显示了结果,但是没显示用户,因此我们需要修改命令,新的命令如下

Get-ADUser -Filter {sAMAccountName -like "J*"} `
| Select-Object Name,@{Name="ADAccountResultantPasswordReplicationPolicy"; `
Expression={Get-ADAccountResultantPasswordReplicationPolicy $_ -DomainController NWTrader-RODC01}} | FT -a

这里使用的技巧是“已计算的属性”,具体介绍可以看这篇文章。新的命令的执行结果如下:

image

这样我们在命令行里得到的结果就和图形界面上的结果基本一致了,虽然命令稍微复杂了点,但是使用命令无疑提高了我们的效率。

最后提一下Get-ADAccountResultantPasswordReplicationPolicy的返回值可能是Allow、DenyExplicit 、DenyImplicit 和Unknown。

本次关于ADAccount相关cmdlets的介绍就到此结束了,敬请期待下次的介绍。

PowerShell V2介绍 (20) - ADComputer

相对于用户账号的管理操作而言,计算机账号的管理操作是比较少的。不过在接下来的介绍中,我们还是按照和用户账号管理一样的顺序来介绍ADComputer相关的cmdlets。当然,Windows PowerShell V2本身也有和计算机相关的cmdlets,在下面的介绍中也会一并介绍。

  • New-ADComputer

首先我们先来看看如何使用New-ADComputer来新建计算机账号。具体命令如下:

New-ADComputer -Path "OU=Computers,OU=NWTrader,dc=nwtrader,dc=com" -Name "NWTRADER-ODJ" -SamAccountName "NWTRADER-ODJ" -Verbose

命令的执行效果如下:

image

新建命令很简单,在默认情况下我们还可以使用“New-ADComputer computername这样的命令形式来创建计算机账号。此时计算机账号将在默认的“Computers容器中创建。而之前的命令则指定了Name,SamAccountName,及Path参数。Name和SamAccountName自然不用说了,而Path参数则指定了具体在哪个OU创建计算机账号。同时默认情况下,计算机账户在创建完成后是默认启用的,也就是Enbaled参数的默认值是True。

和新建用户账号相比,新建计算机账号还是比较简单的,除了刚才提到的几个参数之外,New-ADComputer还有其它几个参数,比如用来记录描述信息的Description,用来跟踪计算机所在位置的Location参数,用来指定计算机管理者的ManagedBy参数,这些参数可以根据生产环境中的实际情况在新建计算机账号时指定。下面让我们来看看如何对计算机账号进行管理。

  • Get-ADComputer和Set-ADComputer

要在Windows PowerShell中进行管理操作,那么必须首先获得要管理的对象,然后才能进行操作。除了使用动词部分是New的cmdlet在新建操作时获得对象外,还有一种方法就是使用动词部分是Get的cmdlet来获得对象。对AD中的计算机而言,Get-ADComputer就是得到对象的cmdlet。下面来看看这个cmdlet的语法。

image

和Get-ADUser一样,在使用Get-ADComputer时,需要指定Filter参数

image

如果没有具体需要的话可以输入通配符*来得到所有计算机的列表,这里同样需要注意如果是在大型环境中计算机数量比较多的话,同样需要指定ResultSetSize,SearchBase及SearchScope参数。在我的测试环境中由于计算机数量不是很多,因此直接指定Filter的参数为*,下面来看下Get-ADComputer -Fileter * | FT Name,SID -a的运行结果:

image

然后我们再来看一个比较实际的例子。

比如我们需要统计当前域内安装的操作系统的情况。大家都能理解从Windows XP + Windows Server 2003到Windows 7 + Windows Server 2008 R2的过渡不是一蹴而就的,期间肯定需要一段过渡时间。在这段时间内,系统管理员可能会比较关心当前域内安装了以上四类操作系统的计算机数量。下面我们就来看看如何使用Get-ADComputer来完成这个任务。

首先我们需要得到所有计算机对象,因此将Get-ADComputer的Filter参数设置为通配符。接着需要注意Get-ADComputer的默认输出是不包含操作系统信息的,因此需要使用Properties参数,参数值是和操作系统信息相关的OperatingSystem, OperatingSystemServicePack, OperatingSystemVersion这三个属性。接下来使用Format-Table格式化输出。最后的命令如下:

Get-ADComputer -Filter * -Properties OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion | FT Name,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion 

而命令的执行效果如下:

image

然后再来看看如何使用Group-Object对结果进行分类汇总。此时的命令如下:

Get-ADComputer -Filter * -Properties OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion | Group OperatingSystem | FT -a 

命令执行效果如下:

image

可以看到在我的测试环境中Windows Server 2008 R2的数量是最多的。当然像安装Exchange时产生的虚拟计算机账号是没有相关操作系统信息的。

接下来说说如何使用Set-ADComputer。和之前修改用户属性的Set-ADUser差不多,我们可以使用Get-ADComputer来获得具体计算机对象,然后使用管道符将计算机对象传递给Set-ADComputer来设置相关属性。比如我们可以为域控制器指定Location属性来表示他们所在的具体物理位置。具体命令如下:

Get-ADComputer NWTrader-DC01 | Set-ADComputer -Location Shanghai
Get-ADComputer NWTrader-RODC01 | Set-ADComputer -Location Beijing

然后我们可以使用以下命令来查看以上两条命令有没有执行成功:

Get-ADComputer -Filter * -SearchBase "OU=Domain Controllers,DC=nwtrader,DC=com" -Properties Location | FT Name,Location

命令的执行过程如下:

image

  • Remove-ADComputer

最后我们来看下Remove-ADComputer,该命令和Remove-ADUser的使用方法一样,只要在命令后加上具体计算机名即可,同样的,删除操作属于高危操作,因此删除时会给出提示。

image

最后我们来看一下Windows 7中PowerShell自带的和域操作相关的两个cmdlet:Add-Computer和Test-ComputerSecureChannel。

Add-Computer是用来加域的cmdlet,现在除了使用之前的图形化界面和netdom命令加域之外,我们又多了一种方式。比如以下命令:

Add-Computer -DomainName NWTrader -Credential NWTrader\Administrator

可以将当前计算机加入NWTrader域,并可以让用户输入相关加域的凭据。

而Test-ComputerSecureChannel用来检查当前计算机和域之间的安全通道是否工作正常,也就是说一台计算机如果长时间关机而没有登录域,我们就可以使用该cmdlet来检查。如果该cmdlet的返回结果是False,则可以尝试使用Repair参数来进行修复。

image

本次关于ADComputer相关cmdlets的介绍就到此结束了,敬请期待下次的介绍。

 

更多内容 下一页 »