为啥驱动器根目录上的 Set-Acl 会尝试设置“对象”的所有权?
Posted
技术标签:
【中文标题】为啥驱动器根目录上的 Set-Acl 会尝试设置“对象”的所有权?【英文标题】:Why does Set-Acl on the drive root try to set ownership of the "object"?为什么驱动器根目录上的 Set-Acl 会尝试设置“对象”的所有权? 【发布时间】:2011-10-01 02:47:20 【问题描述】:我想更改 C:
驱动器的 ACL。我试图做的是删除用户可以直接在驱动器上创建文件夹的权限。我在编写脚本时在另一个文件夹上测试了它。它没有问题。完成后,我在实际驱动器上的测试环境中尝试了该脚本。我得到一个我无法弄清楚的错误。如果我手动删除权限,它可以正常工作。有人有想法吗?
$path = "C:\"
$colRights = [System.Security.AccessControl.FileSystemRights]"CreateDirectories"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("Authenticated Users")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL $path
$objACL.RemoveAccessRule($objACE)
Set-ACL $path $objACL
错误是:
Set-Acl : The security identifier is not allowed to be the owner of this object.
At C:\Users\mhodler\Desktop\Remove Permission.ps1:57 char:8
+ Set-ACL <<<< $path $objACL
+ CategoryInfo : InvalidOperation: (C:\:String) [Set-Acl], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.SetAclCommand
【问题讨论】:
找到了答案。很抱歉在这里发布。我无权在接下来的 4 小时内发布我自己的问题的答案。将 $objACL = Get-ACL $path 替换为 $objACL = (get-item $path).getaccesscontrol("Access") 【参考方案1】:我找到了答案。微软说
很遗憾,
Get-Acl
缺少一些功能。即使您只想修改 DACL,它也会始终读取完整的安全描述符。这就是为什么Set-ACL
也想写所有者即使你没有改变它。使用GetAccessControl
方法可以指定要读取的安全描述符的哪一部分。
将Get-Acl
调用替换为
$acl = (Get-Item $path).GetAccessControl('Access')
【讨论】:
你能引用微软的来源吗? 我能找到的最早的参考文献是 2010 年 12 月 14 日的一篇博客,该博客引用了微软但未注明出处:web.archive.org/web/20120107061856/http://www.bilalaslam.com/… @AnthonyKlotz MS 的回复来自旧 TechNet Powershell 论坛中的 Microsoft 员工“Babak Ramak” - social.technet.microsoft.com/Forums/windowsserver/en-US/…【参考方案2】:您需要SeRestorePrivilege
来设置所有者。我使用来自下面 URL 的 Lee Holmes 的脚本,通过这个额外的 priv 来提升我的流程,并且能够将所有者设置为我以外的其他人。
http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/
我尝试了(get-item $path).getaccesscontrol("access")
方法,但由于我的进程没有SeRestorePrivilege
,所以仍然出现同样的错误。
【讨论】:
非常感谢。通过 Google 找到,帮助我解决了一个完全不同的问题。 谢谢,这就是我的重点。我还发现设置所有者的一种可能解决方法是使用路径的“本地 UNC”版本,例如如果要为 C:\test.txt 设置所有者,则需要在项目上调用 SetAccessControl 方法 (get-item "\\localhost\C$\test.txt") 虽然这可行,但我更喜欢选择的解决方案,而不是使用 (Get-Item $path).GetAccessControl('Access') 来获取 ACL 对象【参考方案3】:以下代码适用于我:
$ApplicationPoolIdentity = "everyone"
function SetACL()
param (
[Parameter(Mandatory=$true)]
[string] $Path
)
$Acl = (Get-Item $Path).GetAccessControl('Access')
Write-Host "Path:" $Path "ID:" $ApplicationPoolIdentity
$Ar = New-Object system.security.accesscontrol.filesystemacces-s-rule($ApplicationPoolIdentity,"Write","Allow")
$Acl.SetAccessRule($Ar)
Write-Host $Acl
$Acl | Set-Acl $Path
SetACL "C:\Test\"
【讨论】:
【参考方案4】:人们可能会发现这更容易:
icacls c:\ /remove "authenticated users"
【讨论】:
【参考方案5】:$Acl = (Get-Item $Path).GetAccessControl('Access')
为我工作。 我从 CMD 运行我的 PS 脚本,在这个 PS 脚本中我运行另一个 PS 脚本,只要我用自己的用户执行,一切正常。当我使用不同的用户时,我得到相同的错误: Set-Acl : 安全标识符不允许是这个对象的所有者。
刚刚将 Get-ACL 更改为上面的那一行,它工作正常。 再次感谢。
【讨论】:
无需创建答案来感谢任何人的其他答案以上是关于为啥驱动器根目录上的 Set-Acl 会尝试设置“对象”的所有权?的主要内容,如果未能解决你的问题,请参考以下文章
使用 set-acl 和 powershell 设置继承和传播标志