导入反序列化AD访问规则时AddAccessRule报错的解决方法及AD对象DACL导出导入方案咨询
导入反序列化AD访问规则时AddAccessRule报错的解决方法及AD对象DACL导出导入方案咨询
兄弟我太懂你这糟心的处境了——20年的AD活成“合法饮酒”的年纪,还被Exchange霍霍得DACLs乱成一锅粥,用原生高级权限工具还动不动卡死,换谁都头大😮💨
先给你解决那个Deserialized对象的报错问题:你猜的没错,Import-Clixml出来的对象确实是序列化后的副本,带了Deserialized.前缀,本质上和原始的System.DirectoryServices.ActiveDirectoryAccessRule不是同一个类型,所以AddAccessRule不认它。解决思路很简单:把反序列化出来的对象属性提取出来,重新创建一个原始类型的ACE对象。
方法一:基于你原来的CliXml方案修复
你不用放弃之前的导出,只需要在导入后重新构建ACE对象就行,甚至还能直接在代码里替换域名,不用手动改XML:
# 导入反序列化的ACE集合 $CleanACLs = Import-Clixml C:\temp\ftw.xml $TestVictom = "AD:CN=Poor User,OU=Employees,DC=prod,DC=myCompany,DC=corp" $acl = get-acl -path $TestVictom foreach ($deserializedAce in $CleanACLs) { # 用反序列化对象的属性,创建原生的ActiveDirectoryAccessRule对象 $newACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule( $deserializedAce.IdentityReference, $deserializedAce.ActiveDirectoryRights, $deserializedAce.AccessControlType, $deserializedAce.ObjectType, $deserializedAce.InheritanceType, $deserializedAce.InheritedObjectType ) # 这里直接替换域名,不用手动改XML $newACE.IdentityReference = $newACE.IdentityReference.Value.Replace("prod.widgets.corp", "prod.myCompany.corp") # 添加到目标ACL $acl.AddAccessRule($newACE) } # 应用修改 Set-Acl -Path $TestVictom -AclObject $acl
方法二:改用CSV导出/导入(更直观易编辑)
如果觉得XML不好手动修改,换成CSV格式会更友好——导出的时候只保留需要的属性,编辑CSV时直接替换域名、删除不需要的行,再导入构建ACE:
1. 从干净环境导出Exchange相关ACE到CSV
$acl = get-acl -path "AD:DC=prod,DC=widgets,DC=corp" $acl.Access | Where-Object { $_.IdentityReference -like "*Exchange*" -or $_.IdentityReference -like "*Organization*" } | Select-Object IdentityReference, AccessControlType, ActiveDirectoryRights, InheritanceType, ObjectType, InheritedObjectType | Export-Csv -Path c:\temp\ftw.csv -NoTypeInformation
2. 编辑CSV文件
- 删除不需要的ACE行
- 批量替换
IdentityReference里的域名(比如把prod.widgets.corp改成prod.myCompany.corp)
3. 导入CSV并应用到目标AD对象
$CleanACLs = Import-Csv C:\temp\ftw.csv $TestVictom = "AD:CN=Poor User,OU=Employees,DC=prod,DC=myCompany,DC=corp" $acl = get-acl -path $TestVictom foreach ($aceRow in $CleanACLs) { # 把CSV里的字符串转换成对应的枚举/ GUID类型 $accessControlType = [System.Security.AccessControl.AccessControlType]$aceRow.AccessControlType $activeDirectoryRights = [System.DirectoryServices.ActiveDirectoryRights]$aceRow.ActiveDirectoryRights $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance]$aceRow.InheritanceType $objectType = [System.Guid]$aceRow.ObjectType $inheritedObjectType = [System.Guid]$aceRow.InheritedObjectType # 创建原生ACE对象 $newACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule( $aceRow.IdentityReference, $activeDirectoryRights, $accessControlType, $objectType, $inheritanceType, $inheritedObjectType ) $acl.AddAccessRule($newACE) } Set-Acl -Path $TestVictom -AclObject $acl
额外提醒
- 测试的时候一定要先在单个对象上验证,没问题再批量操作
- 如果需要处理大量对象,建议加个错误捕获(比如
try/catch),避免中途出错前功尽弃 - Exchange的AD权限确实比较复杂,你可以对比干净环境的权限,过滤掉不需要的ACE再导入,减少冗余
备注:内容来源于stack exchange,提问作者Eric Weintraub
相关产品推荐
相关产品推荐

