从CSV导入权限时Set-ACL报错的PowerShell问题排查
问题:跨系统迁移ACL时Set-Acl报错及Synchronize权限疑问
我通过脚本从某系统导出ACL到CSV,再用另一脚本在新系统读取CSV、创建文件夹结构并应用权限。因安全限制,系统间无法连接,故无法使用robocopy。目前文件夹结构已创建,但ACL无法应用且报错。
测试CSV示例
FolderName,FolderPath,IdentityReference,FileSystemRights,InheritanceFlag user1,DEEPP\Working\user1,AD\user1,Modify,"ContainerInherit, ObjectInherit" user2,DEEPP\Working\user2,AD\user2,Modify,"ContainerInherit, ObjectInherit"
测试脚本
#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 }
报错信息
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
疑问点
单独查看$New_ACL时,输出基本符合预期,但FileSystemRights包含CSV中未定义的Synchronize权限。单独查看$FileSystemRights仅显示Modify。疑问:是否是Synchronize导致脚本报错?若为该问题,如何移除?已知该权限默认会被添加。
问题分析与解决方案
1. 报错核心原因
Set-Acl的-AclObject参数要求传入完整的FileSystemSecurity对象,而非单个FileSystemAccessRule权限规则。你直接传递单个权限规则,这才是报错的根本原因,和Synchronize权限无关。
2. 脚本的其他问题
$FolderPath = $Folder.FolderPath写在循环外,此时$Folder未定义,会导致所有迭代使用无效路径,需移到ForEach循环内部。- 硬编码
$InheritanceFlag = "ContainerInherit",未使用CSV中定义的ContainerInherit, ObjectInherit,需读取CSV值并转换为枚举类型。 - 创建文件夹时未结合
$RootDir生成完整路径,会导致路径错误。
3. 关于Synchronize权限
Synchronize是Windows文件系统的默认权限,指定Modify这类高级权限时会自动包含,属于正常行为,不会引发报错,无需移除。
修正后的脚本
# Create folders and apply AD permissions # Note: Remove drive letter in FolderPath column of csv file (ex, F:\); remove non-AD user rows # Root directory for folder creation $RootDir = "C:\Users\TR\Documents\Scripts\ACL" # Import ACL data from CSV $Folders = Import-Csv "$RootDir\ACLs_Proj-2023-01-25.csv" # Process each folder entry ForEach ($Folder in $Folders) { $fullFolderPath = Join-Path -Path $RootDir -ChildPath $Folder.FolderPath # Create folder if it doesn't exist if (-not (Test-Path $fullFolderPath)) { New-Item -Path $fullFolderPath -ItemType Directory | Out-Null } # Parse parameters from CSV and convert to proper enumeration types $identity = $Folder.IdentityReference $fileSystemRights = [System.Security.AccessControl.FileSystemRights]$Folder.FileSystemRights $inheritanceFlags = [System.Security.AccessControl.InheritanceFlags]($Folder.InheritanceFlag -split ', ' -join ',') $propagationFlags = [System.Security.AccessControl.PropagationFlags]::None $accessControlType = [System.Security.AccessControl.AccessControlType]::Allow # Create the access rule object $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule( $identity, $fileSystemRights, $inheritanceFlags, $propagationFlags, $accessControlType ) # Get existing ACL, add new rule, then apply updated ACL $acl = Get-Acl -Path $fullFolderPath $acl.AddAccessRule($accessRule) Set-Acl -Path $fullFolderPath -AclObject $acl -WhatIf }
关键修正说明
- 使用
Join-Path拼接完整路径,避免路径格式错误。 - 将CSV中的字符串参数转换为对应的.NET枚举类型,确保权限规则的有效性。
- 采用"获取现有ACL→添加新规则→应用完整ACL"的标准流程,符合
Set-Acl的参数要求。 - 移除不必要的
Set-Location,避免路径混淆。 - 保留
-WhatIf参数用于测试,确认无误后可移除该参数以实际应用权限。
内容的提问来源于stack exchange,提问作者tr_cpc1
相关产品推荐
相关产品推荐

