Network-Share

Windows 文件夾權限腳本

  • April 8, 2013

一個客戶端有一個帶有主文件夾的 Windows 域,使用 GPO (\server\share%username%) 定向到共享。

共享具有所有使用者的完全控制權,子文件夾僅需要相關使用者的權限才能在每個文件夾中遞歸地擁有完全控制權,而不是在任何其他子文件夾中。

例如:John 只需要遞歸訪問 \server\share\john 並且不應該能夠瀏覽和訪問 \server\share\peter。

我看過 Icacls 和 set-acl。

文件夾名稱與登錄名相同(Peter 使用使用者名 peter 登錄,John 使用使用者名 john 登錄)

任何指針?

我有一個我寫的 vb.net 類,你可以使用:

要使用它:

Dim userfldr as New UserFolder("\\server\share\%username%", "username")
usrfldr.FixAcl()

編碼:

Imports System.Text

Public Class UserFolder
   Private _folder As System.IO.DirectoryInfo
   Private _security As System.Security.AccessControl.DirectorySecurity
   Private _aclVisible As Boolean = True
   Private _owner As String
   Private _baseDirectory As String
   Private _userName As String
   Private _adminIdentity As Security.Principal.NTAccount
   Private _userIdentity As Security.Principal.NTAccount
   Private _systemIdentity As Security.Principal.NTAccount
   Private _beQuick As Boolean

   Public ReadOnly Property adminIdentity() As Security.Principal.NTAccount
       Get
           Return _adminIdentity
       End Get
   End Property
   Public ReadOnly Property userIdentity() As Security.Principal.NTAccount
       Get
           Return _userIdentity
       End Get
   End Property
   Public ReadOnly Property systemIdentity() As Security.Principal.NTAccount
       Get
           Return _systemIdentity
       End Get
   End Property

   Public ReadOnly Property aclVisible() As Boolean
       Get
           Return _aclVisible
       End Get
   End Property
   Public ReadOnly Property owner() As String
       Get
           Return _owner
       End Get


   End Property
   Public ReadOnly Property HasInheritances() As Boolean
       Get
           Dim returnValue As Boolean = False
           For Each a As System.Security.AccessControl.FileSystemAccessRule In _security.GetAccessRules(True, True, GetType(System.Security.Principal.NTAccount)).OfType(Of System.Security.AccessControl.FileSystemAccessRule)()
               If a.IsInherited Then
                   returnValue = True
                   Exit For
               End If
           Next
           Return returnValue
       End Get
   End Property
   Public ReadOnly Property Users() As String

       Get
           Dim userList As New StringBuilder
           For Each a As System.Security.AccessControl.FileSystemAccessRule In _security.GetAccessRules(True, True, GetType(System.Security.Principal.NTAccount)).OfType(Of System.Security.AccessControl.FileSystemAccessRule)()
               userList.AppendLine(a.AccessControlType.ToString & " " & a.IdentityReference.Value & " (" & a.FileSystemRights.ToString & ")")
           Next
           Return userList.ToString
       End Get
   End Property
   Public ReadOnly Property Folder() As String
       Get
           Return _folder.FullName
       End Get
   End Property
   ''' <summary>
   ''' Creates a new instance of Class
   ''' </summary>
   ''' <param name="directoryTemplate">The path of the directory you want to check user security.  The path should have the variable %username% in it.</param>
   ''' <param name="beQuick">Can Fix ACLs quicker by making only the subfolders inherit, instead of subfolders and files.</param>
   ''' <remarks></remarks>
   Public Sub New(ByVal directoryTemplate As String, ByVal username As String, Optional ByVal beQuick As Boolean = False)
       My.User.InitializeWithWindowsUser()
       _beQuick = beQuick
       _userName = username
       _folder = New IO.DirectoryInfo(directoryTemplate.Replace("%username%", username))
       Dim adSettings As New ADEditor.ADEditorSettings


       _adminIdentity = New Security.Principal.NTAccount(adSettings.domain, "Domain Admins")
       _userIdentity = New Security.Principal.NTAccount(adSettings.domain, _userName)
       _systemIdentity = New Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")



       Try


           My.User.InitializeWithWindowsUser()
           _security = _folder.GetAccessControl(Security.AccessControl.AccessControlSections.All)
           Dim account As System.Security.Principal.NTAccount = _security.GetOwner(GetType(System.Security.Principal.NTAccount))
           _owner = account.Value.Split("\")(1)
       Catch noUserEx As Security.Principal.IdentityNotMappedException


           ' Do Nothing

       Catch ex As Exception

           FixAcl()
       End Try
   End Sub

   Public Sub GiveAdminFullRights()
       _security = _folder.GetAccessControl

       Dim adminFullPermissions As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.FullControl, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
       _security.AddAccessRule(adminFullPermissions)
       _folder.SetAccessControl(_security)

   End Sub
   Public Sub FixAcl(Optional ByVal beQuick As Boolean = False)
       Try


           ' Make Domain Admin Owner so that the code can change permissions
           Dim setOwnerSec As New Security.AccessControl.DirectorySecurity()
           setOwnerSec.SetOwner(adminIdentity)
           _folder.SetAccessControl(setOwnerSec)

           'Make sure that the user's folder doesn't inherit permissions

           _security.SetAccessRuleProtection(True, False)

           ' Clear out existing permissions for the users permissions we are setting
           Dim accessRules As System.Security.AccessControl.AuthorizationRuleCollection

           accessRules = _security.GetAccessRules(True, False, System.Type.GetType("System.Security.Principal.NTAccount"))
           For Each r As System.Security.AccessControl.AuthorizationRule In accessRules
               _security.PurgeAccessRules(r.IdentityReference)
           Next

           ' Declare Permissions
           Dim adminChangePermissions As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.ChangePermissions, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
           Dim adminReadPermissions As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.ReadPermissions, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
           Dim adminListContainers As New Security.AccessControl.FileSystemAccessRule(adminIdentity, Security.AccessControl.FileSystemRights.ListDirectory, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
           Dim userFull As New Security.AccessControl.FileSystemAccessRule(userIdentity, Security.AccessControl.FileSystemRights.FullControl, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
           Dim systemFull As New Security.AccessControl.FileSystemAccessRule(systemIdentity, Security.AccessControl.FileSystemRights.FullControl, Security.AccessControl.InheritanceFlags.ContainerInherit Or Security.AccessControl.InheritanceFlags.ObjectInherit, Security.AccessControl.PropagationFlags.None, Security.AccessControl.AccessControlType.Allow)
           Dim userDeleteDeny As New Security.AccessControl.FileSystemAccessRule(userIdentity, Security.AccessControl.FileSystemRights.Delete, Security.AccessControl.InheritanceFlags.None, Security.AccessControl.PropagationFlags.NoPropagateInherit, Security.AccessControl.AccessControlType.Deny)

           ' Add permissions to security object
           _security.AddAccessRule(adminChangePermissions)
           _security.AddAccessRule(adminReadPermissions)
           _security.AddAccessRule(adminListContainers)
           _security.AddAccessRule(userFull)
           _security.AddAccessRule(userDeleteDeny)
           _security.AddAccessRule(systemFull)
           _security.SetOwner(userIdentity)
           _folder.SetAccessControl(_security)

           ' All files and folders within the user's directory need to inherit
           ' from the user's directory
           If _beQuick Then
               AllowADirectorysDirectoriesandFilesToInheritRecursivelyQuick(_folder.FullName)
           Else
               AllowADirectorysDirectoriesandFilesToInheritRecursively(_folder.FullName)
           End If



           Dim account As System.Security.Principal.NTAccount = _security.GetOwner(GetType(System.Security.Principal.NTAccount))
           _owner = account.Value.Split("\")(1)

       Catch invalidUserEx As System.Security.Principal.IdentityNotMappedException
           MessageBox.Show("The username '" & userIdentity.Value & "' doesn't exist, so the ACL cannot be fixed.", "Invalid user")




       End Try
   End Sub

   Private Sub AllowADirectorysFilesToInherit(ByVal directoryPath As String)

       For Each f As String In IO.Directory.GetFiles(directoryPath)
           Dim fileAcl As New Security.AccessControl.FileSecurity()
           fileAcl.SetOwner(adminIdentity)
           IO.File.SetAccessControl(f, fileAcl)

           fileAcl.SetAccessRuleProtection(False, False)
           fileAcl.SetOwner(userIdentity)
           IO.File.SetAccessControl(f, fileAcl)
       Next

   End Sub

   Private Sub AllowADirectorysDirectoriesandFilesToInheritRecursively(ByVal directoryPath As String)
       AllowADirectorysFilesToInherit(directoryPath)

       For Each d As String In IO.Directory.GetDirectories(directoryPath)
           Dim directoryAcl As New Security.AccessControl.DirectorySecurity
           directoryAcl.SetOwner(adminIdentity)
           IO.Directory.SetAccessControl(d, directoryAcl)

           directoryAcl.SetAccessRuleProtection(False, False)
           directoryAcl.SetOwner(userIdentity)
           IO.Directory.SetAccessControl(d, directoryAcl)

           AllowADirectorysFilesToInherit(d)

           AllowADirectorysDirectoriesandFilesToInheritRecursively(d)
       Next


   End Sub
   Private Sub AllowADirectorysDirectoriesandFilesToInheritRecursivelyQuick(ByVal directoryPath As String)
       AllowADirectorysFilesToInherit(directoryPath)

       For Each d As String In IO.Directory.GetDirectories(directoryPath)
           Dim directoryAcl As New Security.AccessControl.DirectorySecurity
           directoryAcl.SetOwner(adminIdentity)
           IO.Directory.SetAccessControl(d, directoryAcl)

           directoryAcl.SetAccessRuleProtection(False, False)
           directoryAcl.SetOwner(userIdentity)
           IO.Directory.SetAccessControl(d, directoryAcl)

           AllowADirectorysDirectoriesandFilesToInheritRecursivelyQuick(d)
       Next


   End Sub
End Class

如果您希望程式碼為您獲取目錄:

       Dim homePath As String = "\\server\share"
       Dim userName As String
       Dim homeDirectories() As String
       My.User.InitializeWithWindowsUser()
       homeDirectories = IO.Directory.GetDirectories(homePath)

       For Each d As String In homeDirectories

           userName = d.Substring(d.LastIndexOf("\") + 1)

           Dim folder As New UserFolder(d, userName)
           If folder.aclVisible = True Then
                folder.FixAcl()

           End If
       Next

引用自:https://serverfault.com/questions/497065