用于 ACL 失败的 PowerShell SetAccessRule
PowerShell SetAccessRule for ACL failing
我完成的脚本创建了一个文件夹和安全组,这些安全组稍后会以特殊权限添加到相关文件夹中。问题是脚本在“$acl.SetAccessRule($rule_modify)”上失败并抱怨身份。
错误:
"Exception calling "SetAccessRule”,参数为“1”:"Some or all identity references could not be translated."
如果我 运行 通过简单地使用来自 ISE 的 copy/paste 到常规 PowerShell window 脚本逐行 window 使用相同的位置和用户,一切都没有错误。
这是不起作用的重要部分。
#Get ACL list
$acl = Get-Acl -Path $Path
$acl.SetAccessRuleProtection($false,$false)
#Add permission for modify
$set_modify = "INTRA\FIL_$($Department)_$($Group)_Modify", 'DeleteSubdirectoriesAndFiles, Write, ReadAndExecute, Synchronize', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$rule_modify = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $set_modify
$acl.SetAccessRule($rule_modify)
$acl | Set-Acl $path
您可能希望将用于构建安全组名称的所有字符串扩展到一个干净的变量中 - 我发现这可能很棘手。确保 $secgroup
在构建时包含正确的字符串值。
您也可以在一行中创建规则和对象类型。
$secgroup = "INTRA\FIL_$($Department)_$($Group)_Modify"
$modifyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($secgroup,'DeleteSubdirectoriesAndFiles, Write, ReadAndExecute, Synchronize','ContainerInherit, ObjectInherit','None','Allow')
顺便说一句,如果您本质上希望您的用户拥有对内容的修改权限而不能删除父文件夹,那么如果您设置 InheritOnly 标志(我还没有测试过),它应该可以工作。
$modifyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($secgroup,'Modify, Synchronize', 'ContainerInherit, ObjectInherit','InheritOnly','Allow')
我找到了解决方案,但失败了,因为 ActiveDirectory 太慢,无法识别安全组是在 属性 添加到 ACL 之前创建的。
我采用的解决方案是在创建组和文件夹后添加 10 秒休眠,现在它可以正常工作了。
我遇到了基本相同的问题,但 "AddAccessRule"。
$Acl.AddAccessRule($Ar)
我的脚本因上述错误而失败。
正如 Patrik Persson 提到的,在我的情况下,这也是因为 AD 显示新组的速度很慢,并且在安全组出现在我的 AD 中之前无法添加 Ar。
所以我在我想分享的脚本中添加了一个 try/catch 和一个 do/until 循环:
do {
$check = 'ok'
try {
$Acl.AddAccessRule($Ar)
} catch [System.Management.Automation.RuntimeException] {
$_.Exception.Message
$check = 'error'
Start-Sleep -Seconds 2
}
} until (
$check -eq 'ok'
)
如此循环下去,直到AD正确注册安全组。之后将 Ar 添加到 acl,我的脚本将按预期继续。
在远程文件服务器上创建共享时遇到类似问题。
起初,我使用了建议的解决方案(开始-睡眠),但它还不够好,因为它在处理大量共享时显着增加了消耗的时间。
事实证明,您可以在定义 ACE 时使用 SID,并且操作是即时的:
$TempSID = (Get-ADGroup "FIL_$($Department)_$($Group)_Modify").SID
$PermissionModify = "Write, Read, ListDirectory, ReadAndexecute, DeleteSubdirectoriesAndFiles"
$Inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$Propagation = [system.security.accesscontrol.PropagationFlags]"None"
$Type = "Allow"
$modifyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($TempSID, $PermissionModify, $Inherit, $Propagation, $Type)
似乎 Active Directory 需要一些时间(在我的例子中是 2 秒)将 SID 转换为组名(DOMAIN\groupName 格式)。
我完成的脚本创建了一个文件夹和安全组,这些安全组稍后会以特殊权限添加到相关文件夹中。问题是脚本在“$acl.SetAccessRule($rule_modify)”上失败并抱怨身份。
错误: "Exception calling "SetAccessRule”,参数为“1”:"Some or all identity references could not be translated."
如果我 运行 通过简单地使用来自 ISE 的 copy/paste 到常规 PowerShell window 脚本逐行 window 使用相同的位置和用户,一切都没有错误。
这是不起作用的重要部分。
#Get ACL list
$acl = Get-Acl -Path $Path
$acl.SetAccessRuleProtection($false,$false)
#Add permission for modify
$set_modify = "INTRA\FIL_$($Department)_$($Group)_Modify", 'DeleteSubdirectoriesAndFiles, Write, ReadAndExecute, Synchronize', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$rule_modify = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $set_modify
$acl.SetAccessRule($rule_modify)
$acl | Set-Acl $path
您可能希望将用于构建安全组名称的所有字符串扩展到一个干净的变量中 - 我发现这可能很棘手。确保 $secgroup
在构建时包含正确的字符串值。
您也可以在一行中创建规则和对象类型。
$secgroup = "INTRA\FIL_$($Department)_$($Group)_Modify"
$modifyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($secgroup,'DeleteSubdirectoriesAndFiles, Write, ReadAndExecute, Synchronize','ContainerInherit, ObjectInherit','None','Allow')
顺便说一句,如果您本质上希望您的用户拥有对内容的修改权限而不能删除父文件夹,那么如果您设置 InheritOnly 标志(我还没有测试过),它应该可以工作。
$modifyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($secgroup,'Modify, Synchronize', 'ContainerInherit, ObjectInherit','InheritOnly','Allow')
我找到了解决方案,但失败了,因为 ActiveDirectory 太慢,无法识别安全组是在 属性 添加到 ACL 之前创建的。
我采用的解决方案是在创建组和文件夹后添加 10 秒休眠,现在它可以正常工作了。
我遇到了基本相同的问题,但 "AddAccessRule"。
$Acl.AddAccessRule($Ar)
我的脚本因上述错误而失败。 正如 Patrik Persson 提到的,在我的情况下,这也是因为 AD 显示新组的速度很慢,并且在安全组出现在我的 AD 中之前无法添加 Ar。
所以我在我想分享的脚本中添加了一个 try/catch 和一个 do/until 循环:
do {
$check = 'ok'
try {
$Acl.AddAccessRule($Ar)
} catch [System.Management.Automation.RuntimeException] {
$_.Exception.Message
$check = 'error'
Start-Sleep -Seconds 2
}
} until (
$check -eq 'ok'
)
如此循环下去,直到AD正确注册安全组。之后将 Ar 添加到 acl,我的脚本将按预期继续。
在远程文件服务器上创建共享时遇到类似问题。
起初,我使用了建议的解决方案(开始-睡眠),但它还不够好,因为它在处理大量共享时显着增加了消耗的时间。
事实证明,您可以在定义 ACE 时使用 SID,并且操作是即时的:
$TempSID = (Get-ADGroup "FIL_$($Department)_$($Group)_Modify").SID
$PermissionModify = "Write, Read, ListDirectory, ReadAndexecute, DeleteSubdirectoriesAndFiles"
$Inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$Propagation = [system.security.accesscontrol.PropagationFlags]"None"
$Type = "Allow"
$modifyRule = New-Object System.Security.AccessControl.FileSystemAccessRule($TempSID, $PermissionModify, $Inherit, $Propagation, $Type)
似乎 Active Directory 需要一些时间(在我的例子中是 2 秒)将 SID 转换为组名(DOMAIN\groupName 格式)。