You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 17:31:00