我正在尝试在非常大的文件夹树(多个服务器/共享)上应用权限。我运行的脚本,但效率不高,运行时间太长,因为它是按用户和每个文件夹设置的。
我有一个csv文件,其中有三列UserID,Path和offset。以下示例
Domain\OneUser,\\\Server\Share\1\2\3\4\5\6,5<BR>
Domain\TwoUser,\\\Server\Share\1\2\3\4\5\6,5<BR>
Domain\OneUser,\\\Server\Share\1\2\A\B\C\D,5<BR>
Domain\ThreeUser,\\\Server\Share\1\2\A\B\C,5<BR>
Domain\TwoUser,\\\Server\Share\1\2\3\4\5,5
脚本读入文件,然后使用偏移设置每个对象的权限。在此示例中,偏移量为5,这将使脚本停止在1.它还会忽略路径中的最后一个文件夹。
在上面的案例中,OneUser将设置为5,4,3,2,1。然后在5,4,3,2,1上设置TwoUser。然后OneUser将设置在C,B,A,2,1上。其中一些是重复工作,如第3行(在设置之后设置为2和1)。
我不需要为每个单独的文件夹设置权限,而是需要将它们组合在一起,以便将其设置为这样,而不是设置权限23次,这可以在8中完成。
OneUser,Twouser on 5,4,3<BR>
OneUser on C<BR>
OneUser,ThreeUser on B,A<BR>
OneUser,TwoUser,ThreeUser on 2,1
我希望做两件事之一:
将列表导出到csv,如下所示:
OneUser; Twouser,\\服务器\共享\ 1 \ 2 \ 3 \ 4 \ 5 OneUser; Twouser,\\服务器\共享\ 1 \ 2 \ 3 \ 4 \
等等。
或者使用下面的脚本,为每个唯一的文件夹/用户组修改$ objACE和$ objACL以包含每个文件夹的唯一用户
$objACE1 = New-Object System.Security.AccessControl.FileSystemAccessRule(**Domain\OneUser**, $colRights, $InheritanceFlag, $PropagationFlag, $objType<BR>)
$objACE2 = New-Object System.Security.AccessControl.FileSystemAccessRule(**Domain\TwoUser**, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL.AddAccessRule($objACE1)<BR>
$objACL.AddAccessRule($objACE2)
基本上我需要在每个文件夹调用Set-Acl之前添加每个文件夹的所有对象,所以我只对每个文件夹应用一次权限。我还需要排除结束文件夹(其中已存在权限)并告诉它停止的位置。
任何人对如何轻松完成此任务有任何想法?
脚本的这一部分是最重要的,包含设置适当权限所需的所有设置。
#parameters for setting proper traverse/list access to 'This folder only' of parent tree
$colRights = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute,Synchronize"
#turns off inheritance for this permission
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
#ensures 'this folder only' setting of permissions - will not force propogation
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
#specifies that this is an allow access type
$objType = [System.Security.AccessControl.AccessControlType]::Allow
#reads in group/user from csv file to grant permissions for
$objUser = New-Object System.Security.Principal.NTAccount($UserName)
#builds the new access control to program on parent folders
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
#reads in current access control of current parent folder
$objACL = Get-ACL $Container
#adds the access rule to current access controls of the current parent folder
$objACL.AddAccessRule($objACE)
#writes out screen feedback on current status of the script
write-host Setting permissions on $Container for $Username
#Sets access controls on each applicable folder. This does not affect existing permissions, only adds to them.
Set-ACL $container $objACL
答案 0 :(得分:0)
好的,我的建议是制作哈希表以更好地整理您的信息。将密钥设为文件夹,以及需要访问该文件夹的用户的值。通过解析CSV的每一行上的文件夹并遍历它们,您可以构建文件夹列表。然后,对于每个文件夹,检查它是否在哈希表中并将用户添加到该键,或者在需要时创建新密钥。然后循环遍历文件夹,并为每个文件夹添加ACL规则,以便为哈希表中为该文件夹列出的每个用户添加ACL对象。这是我用来做的代码:
$Import = Import-Csv "C:\Path\To\File.csv"
$AllPaths = @{}
$Import | ?{$_.path -match "^(\\.*?)\\[^\\]*$"}|%{
$Subs = $Matches[1].split('\')|Where{![string]::IsNullOrEmpty($_)}
$RootPath = $Subs[0..($Subs.count - $_.Offset - 1)]
For($i=[int]($Subs.count - 1);$i -ge ($Subs.count - $_.Offset);$i--){
$CurPath = "\\{0}\{1}" -f ($RootPath -join '\'),($Subs[($RootPath.count)..$i] -join '\')
If($AllPaths.Keys -contains $CurPath -and $AllPaths[$CurPath] -notcontains $_.User){
$AllPaths[$CurPath]+=$_.User
}elseif($AllPaths.Keys -notcontains $CurPath){
$AllPaths.Add($CurPath,@($_.User))
}
}
}
ForEach($Container in $AllPaths.Keys){
#parameters for setting proper traverse/list access to 'This folder only' of parent tree
$colRights = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute,Synchronize"
#turns off inheritance for this permission
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
#ensures 'this folder only' setting of permissions - will not force propogation
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
#specifies that this is an allow access type
$objType = [System.Security.AccessControl.AccessControlType]::Allow
#reads in current access control of current parent folder
$objACL = Get-ACL $Container
#Add an access rule for each user needing access to this folder to the ACL before writing the ACL back to the folder
ForEach($UserName in $AllPaths[$Container]){
#reads in group/user from csv file to grant permissions for
$objUser = New-Object System.Security.Principal.NTAccount($UserName)
#builds the new access control to program on parent folders
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
#adds the access rule to current access controls of the current parent folder
$objACL.AddAccessRule($objACE)
}
#writes out screen feedback on current status of the script
write-host "Setting permissions on $Container for $($AllPaths[$Container].Values -join ", ")"
#Sets access controls on each applicable folder. This does not affect existing permissions, only adds to them.
Set-ACL $container $objACL
}
使用您的示例数据,我能够编译以下文件夹列表,以及需要访问这些文件夹的关联用户:
PS C:\windows\system32> $AllPaths|ft -AutoSize
Name Value
---- -----
\\Server\Share\1\2\3\4\5 {Domain\OneUser, Domain\TwoUser}
\\Server\Share\1\2\A {Domain\OneUser, Domain\ThreeUser}
\\Server\Share\1\2 {Domain\OneUser, Domain\TwoUser, Domain\ThreeUser}
\\Server\Share\1\2\A\B {Domain\OneUser, Domain\ThreeUser}
\\Server\Share\1 {Domain\OneUser, Domain\TwoUser, Domain\ThreeUser}
\\Server\Share\1\2\3\4 {Domain\OneUser, Domain\TwoUser}
\\Server\Share\1\2\3 {Domain\OneUser, Domain\TwoUser}
\\Server\Share\1\2\A\B\C {Domain\OneUser}
\\Server\Share {Domain\ThreeUser, Domain\TwoUser}