Home > OS >  Powershell problem with Set-ACL from imported csv
Powershell problem with Set-ACL from imported csv

Time:01-31

I've used a script to import ACLs into a csv from one system and have another script to read in the csv, create the folder structure and apply the permissions to a new system. Due to security restrictions, it's not possible for the systems to connect to each other, so robocopy is not an option.

The new folder structure is being created but the ACLs are not applying and I'm getting an error.

Here is a sample of the test csv:

FolderName,FolderPath,IdentityReference,FileSystemRights,InheritanceFlag
user1,DEEPP\Working\user1,AD\user1,Modify,"ContainerInherit, ObjectInherit"
user2,DEEPP\Working\user2,AD\user2,Modify,"ContainerInherit, ObjectInherit"

Here is the test script to read the csv and set the ACLs. Stepping through, I get no errors until the Set-ACL line at the bottom.

#Create folders and apply AD permissions
#Note: Remove drive letter in FolderPath column of csv file (ex, F:\); remove non-AD user rows

# Location Where your folders are to be created
$RootDir = "C:\Users\TR\Documents\Scripts\ACL"
Set-Location "$RootDir" 

# Import CSV file from location
$Folders = Import-Csv "$RootDir\ACLs_Proj-2023-01-25.csv"
$FolderPath = $Folder.FolderPath

# Create Folders from FolderPath column in csv; set ACL
ForEach ($Folder in $Folders) 
{ 

$a = Test-Path $RootDir\$FolderPath #{continue} #{Write-Verbose "Folder: $Path Already Exists"}
if ($a -eq $false) {
 
New-Item $FolderPath -type directory
}
        $IdentityReference = $Folder.IdentityReference
        $FileSystemRights = $Folder.FileSystemRights
        $InheritanceFlag = "ContainerInherit"
        $PropagationFlag = "None"
        $AccessControlType = "Allow"

#New-Object System.Security.AccessControl.FileSystemAccessRule('IdentityReference','FileSystemRights','InheritanceFlags','PropagationFlags','AccessControlType')
$New_ACL = New-Object Security.AccessControl.FileSystemAccessRule $IdentityReference, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $AccessControlType
Set-Acl -Path "$RootDir\$FolderPath" -AclObject $New_ACL -WhatIf
}

Error from the Set-ACL line:

Set-Acl : AclObject
At line:1 char:1
  Set-Acl -Path "$RootDir\$FolderPath" -AclObject $New_ACL -WhatIf
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : InvalidArgument: (System.Security...ystemAccessRule:FileSystemAccessRule) [Set-Acl], ArgumentException
      FullyQualifiedErrorId : SetAcl_AclObject,Microsoft.PowerShell.Commands.SetAclCommand

If I type $New_ACL by itself, I get MOSTLY the expected output for a single entry:

FileSystemRights  : Modify, Synchronize
AccessControlType : Allow
IdentityReference : AD\user2
IsInherited       : False
InheritanceFlags  : ContainerInherit
PropagationFlags  : None

The "mostly" is because, as seen in the csv example, "Synchronize" is not in the FileSystemRights column of my csv file. Typing only $FileSystemRights gives me only the Modify value as expected.

Is the Synchronize entry confusing my poor script, or did I screw up something different? If it's the synchronize, how do I get rid of it? My understanding is that it would be applied by default if not listed.

Thanks!

CodePudding user response:

Ah, ok, so you're exporting a list of Access Control Rules (ACR), and then trying to apply a single rule as an Access Control List. You need a list of rules, not a single rule. Usually what you would do is get the current list of rules, modify it (add more rules or remove unwanted rules), then apply the modified list back to the object.

You obviously know how to get the ACL if you exported it, but I'll include it here. This gives an example of getting the ACL, adding your rule to it, and then applying the updated ACL back to the folder.

# Define the access rule(s) to add to the ACL
$New_ACR = New-Object Security.AccessControl.FileSystemAccessRule $IdentityReference, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $AccessControlType
# Get Access Control List from directory
$ACL = Get-Acl -Path "$RootDir\$FolderPath"
# Add new rule to ACL
$ACL.AddAccessRule($New_ACR)
# Apply updated ACL to directory
Set-Acl -Path "$RootDir\$FolderPath" -AclObject $ACL -WhatIf

CodePudding user response:

OK, the combination of jdweng and MadTech's suggestions fixed the problem. The working test script:

#Create folders and apply AD permissions
#Note: Remove drive letter in FolderPath column of csv file (ex, F:\); remove non-AD user rows

# Location Where your folders are to be created $RootDir = "C:\Users\TR\Documents\Scripts\ACL" Set-Location "$RootDir" 

# Import CSV file from location $Folders = Import-Csv "$RootDir\ACLs_Proj-2023-01-25.csv" $FolderPath = $Folder.FolderPath

# Create Folders from FolderPath column in csv; set ACL ForEach ($Folder in $Folders)  {  if(Test-Path $RootDir\$Folder.FolderPath) {continue} #{Write-Verbose "Folder: $Path Already Exists"} else{   New-Item $Folder.FolderPath -type directory }

        $IdentityReference = $Folder.IdentityReference
        $FileSystemRights = $Folder.FileSystemRights
        $InheritanceFlag = "ContainerInherit"
        $PropagationFlag = "None"
        $AccessControlType = "Allow"

#From stackoverflow response;
# Define the access rule(s) to add to the ACL $New_ACR = New-Object Security.AccessControl.FileSystemAccessRule $IdentityReference, $FileSystemRights, $InheritanceFlag, $PropagationFlag, $AccessControlType
# Get Access Control List from directory $ACL = Get-Acl -Path ($RootDir   "\"   $Folder.FolderPath)
# Add new rule to ACL $ACL.AddAccessRule($New_ACR)
# Apply updated ACL to directory Set-Acl -Path ($RootDir   "\"   $Folder.FolderPath) -AclObject $ACL }

Thanks!

  • Related