Create/add ACL groups

Outok 0 Reputation points
2024-03-23T22:40:00.91+00:00

I am not an expert

I copied folders from two different servers in different domain .

Unfortunately, the folders on the destination server cannot be reached from the users because the ACL groups copied by robocopy are present in the source domain and cannot be managed at the destination domain. To solve the problem I should create new local groups (L) at the destination domain and populate them with the correct users (of the source).

The luck thing is that in the destination domain there are "mirror" groups (they have the same name having the same users >>> change only the last suffixs<<<<)

I can get the name of the group by using the name of each foder (present in the destination) and add it in between the 2 fixd suffix. i.e. if the name of the folder is "financialtax" it can be added in between the two suffix: L. and Write/Read to generate the name group:

“L.financialtax_Write” “L.financialtax_Read”

I was trying to create a script that :

1)given a path (folder path) it parses each folders and sub-folder to catch each "folder name" and add it in between standard suffixs by a variable ($FolderName). L.$FolderName_Write"" L.$FolderName_Read

  1. check those groups (if they are present in the destination domain) and if it exists, then add it in the folders ACL groups. I adapted a script below …but it doesn’t work properly.

It remove the groups present (when created) and replace them with the groups generated by the script instead of add them.

Another issue is the inheritance. The groups present in the parent folder should be propagated within each individual subfolder until the last file (but it does't happen)

function Set-ACLRecursive { param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [System.IO.DirectoryInfo]$Folder ) 
# get the folder name 
$FolderName = $Folder.Name 
# Build the name of the groups 
$ReadGroupName = "L.$FolderName_Read" $WriteGroupName = "L.$FolderName_Write" 
# get group SID 
$ReadGroupSID = (Get-ADGroup $ReadGroupName).SID $WriteGroupSID = (Get-ADGroup $WriteGroupName).SID 
# Folder ACL 
$ACL = Get-Acl -Path $Folder.FullName $ACL.SetAccessRuleProtection($true, $false) 
# Remove permission 
$ACL.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule($ReadGroupSID, "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"))) $ACL.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule($WriteGroupSID, "Modify", "ContainerInherit,ObjectInherit", "None", "Allow"))) Set-Acl -Path $Folder.FullName -AclObject $ACL 
#Set ACL permissions for the sub-folder 
foreach ($SubFolder in $Folder.GetDirectories()) { Set-ACLRecursive $SubFolder } } 
#Path Root folder 
$RootFolder = “C:\path\folder” 
#Function call to start scanning 
Set-ACLRecursive (Get-Item $RootFolder)
Windows Server
Windows Server
A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.
13,229 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,551 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,595 questions
{count} votes

2 answers

Sort by: Most helpful
  1. guilherme rodrigues 315 Reputation points
    2024-04-01T23:39:19.32+00:00

    Your script is currently removing existing ACL entries and replacing them with new ones, instead of adding the new entries to the existing ones.

    The script should ensure that the permissions set on a parent folder are inherited by all its subfolders and files.

    function Set-ACLRecursive {
        param (
            [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
            [System.IO.DirectoryInfo]$Folder
        )
        # Get the folder name
        $FolderName = $Folder.Name
        # Build the name of the groups
        $ReadGroupName = "L.$FolderName_Read"
        $WriteGroupName = "L.$FolderName_Write"
        # Check if groups exist in AD and get their SID
        $ReadGroup = Get-ADGroup -Filter { Name -eq $ReadGroupName } -ErrorAction SilentlyContinue
        $WriteGroup = Get-ADGroup -Filter { Name -eq $WriteGroupName } -ErrorAction SilentlyContinue
        if ($ReadGroup -and $WriteGroup) {
            $ReadGroupSID = $ReadGroup.SID
            $WriteGroupSID = $WriteGroup.SID
            # Get current ACL
            $ACL = Get-Acl -Path $Folder.FullName
            # Create ACL rules
            $ReadRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                $ReadGroupSID, "ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow")
            $WriteRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                $WriteGroupSID, "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
            # Add ACL rules to ACL object
            $ACL.AddAccessRule($ReadRule)
            $ACL.AddAccessRule($WriteRule)
            # Apply the modified ACL to the folder
            Set-Acl -Path $Folder.FullName -AclObject $ACL
        } else {
            Write-Warning "One or both groups ($ReadGroupName, $WriteGroupName) do not exist in AD."
        }
        # Set ACL permissions for sub-folders recursively
        foreach ($SubFolder in $Folder.GetDirectories()) {
            Set-ACLRecursive $SubFolder
        }
    }
    # Path Root folder
    $RootFolder = "C:\path\to\folder"
    # Function call to start scanning
    Set-ACLRecursive (Get-Item $RootFolder)
    
    

    Before attempting to add ACL entries, the script now checks if the groups actually exist in Active Directory. This avoids errors if the groups are missing.

    Instead of setting the ACL object's protection and removing all existing rules, the script now adds new access rules to the existing ACL object. This ensures that existing permissions are preserved.

    The ContainerInherit,ObjectInherit flags on the FileSystemAccessRule objects ensure that the permissions are inherited by subfolders and files.

    0 comments No comments

  2. Outok 0 Reputation points
    2024-04-14T18:52:25.0466667+00:00

    Thank you guilherme rodrigues,

    I tested your script and over-all it works but I need to adjust twoparts:

    1. the Local folder groups are not propagated to subfolders and files that do not have any associated Folder groups (below an image that explains what I mean)

    User's image

    Probably it can be fixed by adding

    $ACL.SetAccessRuleProtection($false,$true)

      1. I am receiving an erroro because it seems that the "ContainerInherit,ObjectInherit" command cannot be associated with files (because it has no associated child) so I thought I could add the command that check if the file is a folder or a file

      if($folder.PSIscontainer)

      This new condition should divide the setting from folder to file that should be for the file:

    $WriteRule = New-Object System.Security.AccessControl.FileSystemAccessRule( $WriteGroupSID, "Modify", "None", "None", "Allow")

    But I was not able to add it.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.