PowerShell 学习笔记 (2):批量创建带有特定ACL的文件夹
本文在ITECN首发,未经许可严禁转载。
看了下昨天笔记1的浏览量,似乎大家对PowerShell很感兴趣。因此今天再为诸位奉献一篇学习笔记。同时在这里也问诸位一个问题,各位需要我在单篇笔记里讲一些基本的东西么?比如变量的使用,条件,循环语句等的简单例子。还是希望我以后的每篇笔记都是一个问题情景为主,在这之中穿插一部分有关基础知识的讲解。欢迎大家留言,发表你的看法。
今天我们需要用PowerShell处理的问题是这个:批量创建带有特定ACL的文件夹。作为管理员有时会遇到这样的情况:公司招聘了100名左右的新员工,IT经理要求为新员工在文件服务器上每人创建一个文件夹,并将权限设置为只有IT部门,各部门经理,及员工本人才能查看和修改该文件夹的内容。
这样问题就产生了,创建100个左右的文件夹并设置权限,如果在图形界面下操作的话将会是一件枯燥又乏味的事。当然在PowerShell之前,我们可以借助VBS脚本(KB:825751)或者其它手段实现(诸位可以阅读"主文件夹另类用法"这篇文章)。而当各位阅读过825751这篇KB后,也会发现xcacls这个脚本的使用也是非常复杂的。因此当PowerShell横空出世后,人们自然会来看看PowerShell在设置ACL方面有什么新的变化。
当然,回答是肯定的。PowerShell提供了Get-ACL和Set-ACL两个cmdlet。这两个命令的简单应用如下:
Get-ACL w:\test\test1.txt | Set-ACL w:\test\test2.txt
简而言之就是用Get-ACL获得对象的访问控制列表,然后用Set-ACL将得到的访问控制列表应用到其它对象上。这样看的话似乎这两个命令的功能也不是很强,不过我们需要牢记的一点是PowerShell是基于.net的,我们可以用.net对象来进行操作。
这里插入一段题外话。对很多ITpro而言,.net是开发人员用的,因此也不会把太多时间花在这上。但是我们在实际工作中时不时会遇到需要写一段脚本来解决的问题。很多人的办法就是通过访问脚本中心或者搜索来解决问题。那么对于.net而言,其实我们也可以通过搜索解决问题,在不知道具体.net方法的情况下。昨天我在思考“批量创建带有特定ACL的文件夹”这个问题时,我也是通过搜索知道如何利用.net配合PowerShell来设置ACL。昨天我的搜索关键词是“PowerShell Set-ACL”,搜索结果的第四个正是我需要的内容。在该页面提供的脚本基础之上,我完成了以下代码。
(由于页面问题部分换行的代码应在一行内)
|
$ACLTempfld = "w:\vistatest\bob"
$domain = $env:userdomain
$Targetfld = "w:\vistatest\"
$AccessRights = "Modify"
$AccessControl ="Allow"
function NewFolders {
$fld = ni -path $Targetfld$_ -type directory -ErrorAction:SilentlyContinue
}
function CustomSetACL {
NewFolders $_
$TemplateACL = Get-Acl $args
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
#Creat new Dot Net object
$user = "$domain\$_"
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule($user,$AccessRights, $inherit, $propagation, $AccessControl)
$TemplateACL.AddAccessRule($accessrule)
Set-Acl -aclobject $TemplateACL -path $Targetfld$_
Write-Output "$user - Operation Successed!"
}
gc w:\test\users.txt | foreach {CustomSetACL $ACLtempfld} |
下面我们来谈谈其中的具体内容
$ACLTempfld = "w:\vistatest\bob"
这是提供ACL模板的文件夹,可以在这个文件夹上设置相应权限(IT部门,部门经理),这里需要注意的是一开始不要设置具体用户的权限,否则当脚本开始执行ACL复制时,那么该用户(比如bob)也就有访问其它用户文件夹的权限了。我们在脚本执行完成后再来添加该文件夹具体用户的权限。
$domain = $env:userdomain
这是用来储存用户所在域的环境变量。如果用户在工作组环境下,那么就是计算机名比如“Workstation”,如果在域环境中就是域名,比如“Contoso”
$Targetfld = "w:\vistatest\"
这是用存放目标文件夹的变量。该文件夹用来存放各个用户文件夹。
$AccessRights = "Modify"
这是储存访问权限的变量。可以设定的内容可以参考MSDN上的这篇文档:
http://msdn2.microsoft.com/zh-cn/library/system.security.accesscontrol.filesystemrights(VS.80).aspx
$AccessControl ="Allow"
这是用来储存具体访问控制的变量,其值是Allow或Deny中的任意一个。
然后我们看到脚本的最下方。gc w:\test\user.txt
gc是get-content的别名,用来获得文本文件里面的内容。users.txt里面则是形如以下格式的内容。每个用户的登录名各占一行。然后gc将获得的内容传递到“|”右边。我们通过foreach来对每一个对象(指anna,clover等)来执行CustomSetACL 操作。
|
anna
clover
bill
jack
jenny |
下面我们来看看具体的两个Function里面的内容。
首先是NewFolders。这个比较简单就是用来创建文件的。使用的cmdlet是new-item(别名 ni)。具体的使用方法各位可以用get-help new-item -full来查看。$Targetfld$_,这个一看上去看不太懂,其实就是文件夹路径,比如“w:\vistatest\anna”。和vbs相比,PowerShell可以这样处理字串自建的合并。 -ErrorAction:SlientlyContinue则表示出错后不显示错误提示,比如文件夹已存在的情况下。
上述内容实现的是问题情景中的批量创建。而下面的内容则完成了设置ACL的工作。
然后我们再来看看CustomSetACL。这就是用来设置ACL代码。这里与其让我这个.net门外汉来解释具体方法,还不如大家来阅读MSDN的标准说明来的准确。http://msdn2.microsoft.com/zh-cn/library/sfe70whw(VS.80).aspx
这里我们需要注意的是 $user 是存放形如“Workstation\anna”或者“contoso\anna”的用户名,具体用户必须在系统中存在否则脚本将会出错。而AddAccessRule则是向已存在的ACL中添加内容。其中的具体参数,大家可以看我上面给出的MSDN文档链接。
下面我们再来看看脚本的具体使用方法。
1. 我们先创建提供ACL的模板文件夹,比如bob,然后设置相应权限,注意此时先不要设置具体用户权限。
2. 然后我们编辑PowerShell脚本,主要是根据需要调整脚本开始的四个变量(第1,3,4,5行)
3. 然后我们再配置PowerShell能执行脚本。(如果你还没配置的话,配置了话可以省略这步。)
http://www.microsoft.com/technet/technetmag/issues/2007/09/PowerShell/default.aspx?loc=zh
具体解释可以看上面这篇文章。具体命令是
Set-ExecutionPolicy RemoteSigned
4. 然后在PowerShell界面中,输入脚本名(可以输入打头字母,然后按Tab键,最好就是这样操作,原因可以看上面的链接。)然后回车执行即可。
5.执行结果(为了不在登陆界面上显示,举例用的五个用户我都禁用了)
6.最后我们再对模板文件夹设置权限(比如设置bob用户的Modify权限。)
*注意事项
请确保用合适权限执行脚本,比如我现在就是以管理员身份运行PowerShell的。而Vistatest文件夹ghjconan则拥有完全控制权限。
这样我们就用PowerShell解决了一个具体问题,不知道诸位对这篇文章满意否?