Windows 文件夹权限脚本

Windows 文件夹权限脚本

一个客户端有一个带有主文件夹的 Windows 域,使用 GPO(\server\share\%username%)定向到共享。

共享具有所有用户的完全控制权,并且子文件夹只需要相关用户的权限即可在每个文件夹中递归地拥有完全控制权,而无需在任何其他子文件夹中拥有完全控制权。

例如:John 只需要递归访问 \server\share\john,而不能浏览和访问 \server\share\peter。

我已经看过 Icacls 和 set-acl。

文件夹名称与登录名相同(Peter 使用用户名 peter 登录,John 使用用户名 john 登录)

有什么指点吗?

答案1

我有一个自己编写的 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

相关内容