chaiyi 2007-11-26 23:24
PowerShell 学习笔记 (2):批量创建带有特定ACL的文件夹
今天我们需要用PowerShell处理的问题是这个:批量创建带有特定ACL的文件夹。作为管理员有时会遇到这样的情况:公司招聘了100名左右的新员工,IT经理要求为新员工在文件服务器上每人创建一个文件夹,并将权限设置为只有IT部门,各部门经理,及员工本人才能查看和修改该文件夹的内容。
这样问题就产生了,创建100个左右的文件夹并设置权限,如果在图形界面下操作的话将会是一件枯燥又乏味的事。当然在PowerShell之前,我们可以借助VBS脚本(KB:[url=http://support.microsoft.com/kb/825751][color=#800080]825751[/color][/url])或者其它手段实现(诸位可以阅读"[url=http://bbs.winos.cn/viewthread.php?tid=3316][color=#0000ff]主文件夹另类用法[/color][/url]"这篇文章)。而当各位阅读过825751这篇KB后,也会发现xcacls这个脚本的使用也是非常复杂的。因此当PowerShell横空出世后,人们自然会来看看PowerShell在设置ACL方面有什么新的变化。
当然,回答是肯定的。PowerShell提供了Get-ACL和Set-ACL两个cmdlet。这两个命令的简单应用如下:
[size=10pt]Get-ACL w:\test\test1.txt | Set-ACL w:\test\test2.txt[/size][size=10pt][/size]
简而言之就是用Get-ACL获得对象的访问控制列表,然后用Set-ACL将得到的访问控制列表应用到其它对象上。这样看的话似乎这两个命令的功能也不是很强,不过我们需要牢记的一点是PowerShell是基于.net的,我们可以用.net对象来进行操作。
这里插入一段题外话。对很多ITpro而言,.net是开发人员用的,因此也不会把太多时间花在这上。但是我们在实际工作中时不时会遇到需要写一段脚本来解决的问题。很多人的办法就是通过访问脚本中心或者搜索来解决问题。那么对于.net而言,其实我们也可以通过搜索解决问题,在不知道具体.net方法的情况下。昨天我在思考“批量创建带有特定ACL的文件夹”这个问题时,我也是通过搜索知道如何利用.net配合PowerShell来设置ACL。昨天我的搜索关键词是“PowerShell Set-ACL”,搜索结果的第四个正是我需要的[url=http://blog.netnerds.net/2007/07/powershell-set-acl-does-not-appear-to-work/][color=#0000ff]内容[/color][/url]。在该页面提供的脚本基础之上,我完成了以下代码。
(由于页面问题部分换行的代码应在一行内)
[table=98%,#e5e5e5][tr][td][align=left][size=10pt]$ACLTempfld[/size][size=10pt] = [/size][size=10pt]"w:\vistatest\bob"[/size][size=10pt][/size][/align]
[align=left][size=10pt]$domain[/size][size=10pt] = [/size][size=10pt]$env:userdomain[/size]
[size=10pt][/size][/align]
[align=left][size=10pt]$Targetfld[/size][size=10pt] = [/size][size=10pt]"w:\vistatest\"[/size][size=10pt][/size][/align]
[align=left][size=10pt]$AccessRights[/size][size=10pt] = [/size][size=10pt]"Modify"[/size]
[size=10pt][/size][/align]
[align=left][size=10pt]$AccessControl[/size][size=10pt] =[/size][size=10pt]"Allow"[/size][size=10pt][/size][/align]
[align=left][size=10pt]function[/size][size=10pt] NewFolders {[/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$fld[/size][size=10pt] = ni -path [/size][size=10pt]$Targetfld[/size][size=10pt]$_[/size][size=10pt] -type directory -ErrorAction:SilentlyContinue[/size][/align]
[align=left][size=10pt]}[/size][/align]
[align=left][size=10pt]function[/size][size=10pt] CustomSetACL
{[/size][/align]
[align=left][size=10pt]
NewFolders [/size][size=10pt]$_[/size][size=10pt][/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$TemplateACL[/size][size=10pt] = [/size][b][size=10pt]Get-Acl[/size][/b]
[size=10pt]$args[/size][size=10pt][/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$inherit[/size][size=10pt] = [[/size][size=10pt]system.security.accesscontrol.InheritanceFlags[/size][size=10pt]][/size][size=10pt]"ContainerInherit, ObjectInherit"[/size][size=10pt][/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$propagation[/size][size=10pt] = [[/size][size=10pt]system.security.accesscontrol.PropagationFlags[/size][size=10pt]][/size][size=10pt]"None"[/size][size=10pt][/size][/align]
[align=left][size=10pt]
[/size][size=10pt]#Creat new Dot Net object[/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$user[/size][size=10pt] =
[/size][size=10pt]"$domain\$_"[/size][size=10pt][/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$accessrule[/size][size=10pt] = [/size][b][size=10pt]New-Object[/size][/b][size=10pt] system.security.AccessControl.FileSystemAccessRule([/size][size=10pt]$user[/size][size=10pt],[/size][size=10pt]$AccessRights[/size][size=10pt], [/size][size=10pt]$inherit[/size][size=10pt], [/size][size=10pt]$propagation[/size][size=10pt], [/size][size=10pt]$AccessControl[/size][size=10pt])[/size][/align]
[align=left][size=10pt]
[/size][size=10pt]$TemplateACL[/size][size=10pt].AddAccessRule([/size][size=10pt]$accessrule[/size][size=10pt])[/size][/align]
[align=left][size=10pt]
[/size][b][size=10pt]Set-Acl[/size][/b]
[i][size=10pt]-aclobject[/size][/i]
[size=10pt]$TemplateACL[/size]
[i][size=10pt]-path[/size][/i]
[size=10pt]$Targetfld[/size][size=10pt]$_[/size][size=10pt][/size][/align]
[align=left][size=10pt]
[/size][b][size=10pt]Write-Output[/size][/b]
[size=10pt]"$user - Operation Successed!"[/size][size=10pt][/size][/align]
[align=left][size=10pt]}[/size][/align]
[size=10pt]gc w:\test\users.txt | [/size][size=10pt]foreach[/size][size=10pt] {CustomSetACL [/size][size=10pt]$ACLtempfld[/size][size=10pt]}[/size]
[/td][/tr][/table]下面我们来谈谈其中的具体内容
[align=left][size=10pt]$ACLTempfld[/size][size=10pt] = [/size][size=10pt]"w:\vistatest\bob" [/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]这是提供ACL模板的文件夹,可以在这个文件夹上设置相应权限(IT部门,部门经理),这里需要注意的是一开始不要设置具体用户的权限,否则当脚本开始执行ACL复制时,那么该用户(比如bob)也就有访问其它用户文件夹的权限了。我们在脚本执行完成后再来添加该文件夹具体用户的权限。[/color][/font][/size][/align]
[align=left][size=10pt]$domain[/size][size=10pt] = [/size][size=10pt]$env:userdomain[/size]
[/align]
[align=left][size=10pt][font=宋体][color=#000000]这是用来储存用户所在域的环境变量。如果用户在工作组环境下,那么就是计算机名比如“Workstation”,如果在域环境中就是域名,比如“Contoso”[/color][/font][/size][/align]
[align=left][size=10pt]$Targetfld[/size][size=10pt] = [/size][size=10pt]"w:\vistatest\"[/size][/align]
[align=left]
[size=10pt][font=宋体][color=#000000]这是用存放目标文件夹的变量。该文件夹用来存放各个用户文件夹。[/color][/font][/size][/align]
[align=left][size=10pt]$AccessRights[/size][size=10pt] = [/size][size=10pt]"Modify"[/size]
[/align]
[align=left][size=10pt]这是储存访问权限的变量。可以设定的内容可以参考MSDN上的这篇文档:[/size][/align]
[align=left][size=10pt][url=http://msdn2.microsoft.com/zh-cn/library/system.security.accesscontrol.filesystemrights(VS.80).aspx][color=#0000ff]http://msdn2.microsoft.com/zh-cn/library/system.security.accesscontrol.filesystemrights(VS.80).aspx[/color][/url][/size][/align]
[align=left][size=10pt]$AccessControl[/size][size=10pt] =[/size][size=10pt]"Allow"[/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]这是用来储存具体访问控制的变量,其值是Allow或Deny中的任意一个。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]然后我们看到脚本的最下方。gc w:\test\user.txt[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]gc是get-content的别名,用来获得文本文件里面的内容。users.txt里面则是形如以下格式的内容。每个用户的登录名各占一行。然后gc将获得的内容传递到“|”右边。我们通过foreach来对每一个对象(指anna,clover等)来执行[/color][/font][/size][size=10pt]CustomSetACL[/size] 操作。[/align]
[table=98%,#e5e5e5][tr][td]anna
clover
bill
jack
jenny
[/td][/tr][/table][align=left][size=10pt][font=宋体][color=#000000]下面我们来看看具体的两个Function里面的内容。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]首先是NewFolders。这个比较简单就是用来创建文件的。使用的cmdlet是new-item(别名 ni)。具体的使用方法各位可以用get-help new-item -full来查看。$Targetfld$_,这个一看上去看不太懂,其实就是文件夹路径,比如“w:\vistatest\anna”。和vbs相比,PowerShell可以这样处理字串自建的合并。 -ErrorAction:SlientlyContinue则表示出错后不显示错误提示,比如文件夹已存在的情况下。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]上述内容实现的是问题情景中的批量创建。而下面的内容则完成了设置ACL的工作。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]然后我们再来看看CustomSetACL。这就是用来设置ACL代码。这里与其让我这个.net门外汉来解释具体方法,还不如大家来阅读MSDN的标准说明来的准确。[url=http://msdn2.microsoft.com/zh-cn/library/sfe70whw(VS.80).aspx][color=#0000ff]http://msdn2.microsoft.com/zh-cn/library/sfe70whw(VS.80).aspx[/color][/url][/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]这里我们需要注意的是 $user 是存放形如“Workstation\anna”或者“contoso\anna”的用户名,具体用户必须在系统中存在否则脚本将会出错。而AddAccessRule则是向已存在的ACL中添加内容。其中的具体参数,大家可以看我上面给出的MSDN文档链接。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]下面我们再来看看脚本的具体使用方法。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]1. 我们先创建提供ACL的模板文件夹,比如bob,然后设置相应权限,注意此时先不要设置具体用户权限。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]2. 然后我们编辑PowerShell脚本,主要是根据需要调整脚本开始的四个变量(第1,3,4,5行)[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]3. 然后我们再配置PowerShell能执行脚本。(如果你还没配置的话,配置了话可以省略这步。)[/color][/font][/size][/align]
[align=left][size=10pt][url=http://www.microsoft.com/technet/technetmag/issues/2007/09/PowerShell/default.aspx?loc=zh][color=#0000ff]http://www.microsoft.com/technet/technetmag/issues/2007/09/PowerShell/default.aspx?loc=zh[/color][/url][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]具体解释可以看上面这篇文章。具体命令是[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]Set-ExecutionPolicy RemoteSigned[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]4. 然后在PowerShell界面中,输入脚本名(可以输入打头字母,然后按Tab键,最好就是这样操作,原因可以看上面的链接。[/color][/font][/size][size=10pt][font=宋体][color=#000000])然后回车执行即可。[/color][/font][/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]5.执行结果(为了不在登陆界面上显示,举例用的五个用户我都禁用了)[/color][/font][/size][/align]
[align=left][size=10pt][url=http://blogs.itecn.net/blogs/ghjconan/WindowsLiveWriter/PowerShell2ACL_BB6C/image.png][img=944,564]http://blogs.itecn.net/blogs/ghjconan/WindowsLiveWriter/PowerShell2ACL_BB6C/image_thumb.png[/img][/url] [/size][/align]
[align=left][size=10pt][font=宋体][color=#000000]6.最后我们再对模板文件夹设置权限(比如设置bob用户的Modify权限。)[/color][/font][/size][/align]
[[i] 本帖最后由 chaiyi 于 2007-12-2 16:18 编辑 [/i]]
aspirer 2007-11-29 14:08
[quote]原帖由 [i]chaiyi[/i] 于 2007-11-26 23:25 发表 [url=http://www.sharecenter.net/redirect.php?goto=findpost&pid=1906390&ptid=189816][img]http://www.sharecenter.net/images/common/back.gif[/img][/url]
注意所有的表情都是两点: [/quote]
你可以编辑一下,编辑的时候 将“禁用smiles" 勾选上
[[i] 本帖最后由 aspirer 于 2007-11-29 14:09 编辑 [/i]]