为啥驱动器根目录上的 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 设置继承和传播标志

为啥 Nucleo 144 上的引脚没有输出足够高的电压,尽管输出设置为 HIGH?

win10系统为啥老是自动重启

为啥使用JAVA的时候老显示内存不足?

为啥我电脑上的字体都变成绿色的了,求解决方案

为啥 Python 会找到与 Windows 不同的文件大小?