我想在Set-ACL
AD DS 对象1上运行“域管理员”在我构建的 ACL 对象中设置为所有者。代码基本上如下所示2:
Function SetDSAcl {
Param (
[Microsoft.ActiveDirectory.Management.ADObject]$targetObject # target object
)
$targetACL = Get-Acl "AD:\$($targetObject.DistinguishedName)"
# [some voodoo to get the values for my new ACE]
# Create a new AccessRule using the object constructor
# $newAce = New-Object System.DirectoryServices.ActiveDirectoryAccessRule([...])
# Add the generated ACE to target's ACL
$targetAcl.AddAccessRule($newAce)
# Persist the changed ACL to the object
Set-ACL -AclObject $targetAcl "AD:\$($targetObject.DistinguishedName)"
}
但是,当在 Server 2008 R2 DC(Powershell v5)上执行代码时,Set-ACL 调用返回此错误:
Set-ACL : This security ID may not be assigned as the owner of this object
或者当使用相同的安全主体从 Server 2012 R2 管理站(Powershell v4)运行它时出现更通用的“访问被拒绝”异常:
Set-ACL : Access is denied
我甚至没有改变在这种特殊情况下,所有者是所有者,但显然 Set-ACL 只是重写整个安全描述符。
“修改权限”和“修改所有者”已在目标对象上明确设置,我完全能够使用 gpmc.msc GUI 将此对象的所有者更改为我想要的任何所有者,无论是在 DC 还是在管理站上,因此这不是一个明显的权限问题。另一方面,我还看到代码在由属于域管理员团体。
我使用的帐户故意没有“域管理员”成员身份(而是“BUILTIN\Server Admins”组的成员),但需要能够自由设置对象的所有者。我看到MSDN 文章介绍了此错误消息建议“了解您有权指定哪些用户和组为所有者”,这对我的情况没有帮助。
那么我做错了什么?
1在我的例子中是 GPO,但对象的类型并不那么重要,例如,我也看到过它发生在 OU 中。
2该Set-Acl -AclObject $targetAcl -Path "AD:\$($targetObject.DistinguishedName)"
调用看起来像是黑客行为,事实也确实如此。我无法像预期的那样直接传递给-InputObject $targetObject
实现该方法的对象类型,而 [Microsoft.ActiveDirectory.Management.ADObject] 出于某些神秘原因并未这样做。Set-ACL
InputObject
SetSecurityDescriptor
答案1
由于我发现我看到的效果可能是特定于 Set-ACL 的实现,因此我尝试获取 [System.DirectoryServices.ActiveDirectorySecurity] 类并使用其 .SetOwner 方法:
$adsiTarget = [adsi]"LDAP://$($targetObject.DistinguishedName)"
$idRef = New-Object System.Security.Principal.NTAccount("CONTOSO", "Domain Admins")
$adsiTarget.PSBase.ObjectSecurity.SetOwner($idRef)
$adsiTarget.PSBase.CommitChanges()
在我最初在 DC 上运行代码的测试中,我被这样一个事实所困扰:如果我想将所有者设置为我自己(取得所有权),它可以工作,但再次无法将所有者设置为域管理员:
Exception calling "CommitChanges" with "0" argument(s): "A constraint violation occurred.
幸运的是,我偶然发现了“Set-ACL 失败”问题的答案这里是 SF,链接为“相关”。此答案提到令牌特定的特权限制1 可能是导致问题的原因,因此我继续在管理站上测试相同的方法,其中本地交互式 DC 令牌限制不适用。它起作用了 - 我现在可以根据自己的喜好在 Powershell 中设置 DS 对象的所有者(只要我不尝试在 DC 上这样做)。
TechNet 论坛中的另一个主题正在提供一个基于 .NET 类的解决方案,将此权限添加到当前进程令牌,而无需使用 PSCX 等第三方 Cmdlet,但我还没有找到在我的特定情况下使其发挥作用的方法。
1这里的相关特权可能是恢复特权- 默认情况下,它对交互式登录过程令牌是禁用的。
这也意味着需要更改 AD DS 对象所有权的帐户需要通过默认 BUILTIN 组(例如 DC 上的服务器操作员和备份操作员)中的组成员身份或通过更改默认域控制器策略分配的“还原文件和目录”用户权限来分配此特权。