Powershell,Set-Acl,如何将用户排序到文件夹并应用权限一次

时间:2015-01-27 21:18:33

标签: powershell csv permissions

我正在尝试在非常大的文件夹树(多个服务器/共享)上应用权限。我运行的脚本,但效率不高,运行时间太长,因为它是按用户和每个文件夹设置的。

我有一个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

我希望做两件事之一:

  1. 将列表导出到csv,如下所示:

    OneUser; Twouser,\\服务器\共享\ 1 \ 2 \ 3 \ 4 \ 5 OneUser; Twouser,\\服务器\共享\ 1 \ 2 \ 3 \ 4 \

  2. 等等。

    或者使用下面的脚本,为每个唯一的文件夹/用户组修改$ 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 
    

1 个答案:

答案 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}