На ряде серверов, где я работаю, разрешения на общие папки загромождены прямыми разрешениями для некоторых наших техников, поскольку им нужно взять на себя ответственность. Я понял, как исправить проблему с владением, чтобы она больше не возникала, но я застрял на очистке этих разрешений. К сожалению, когда я запускаю эту команду, ничего не происходит, даже ошибки. Я предполагаю, что это какая-то логическая ошибка с моей стороны, но я не могу ее обнаружить. Любая помощь будет оценена по достоинству.
# $vData is the root path
Get-Item $vData | foreach { $_ ; $_ | Get-ChildItem -directory -Force -Recurse }| foreach { $currentDir = $_; $acl = ($_ | Get-Acl).Access; $IDs = $acl | select identityreference ; foreach ($ID in $IDs) { if (($ID.ToString()).endswith('-admin')) { $acesToRemove = $acl | where{ $_.IsInherited -eq $false -and $_.IdentityReference -eq $ID }; $acl.RemoveAccessRuleAll($acesToRemove); Set-Acl -AclObject $acl $currentDir.ToString(); } } }
так как текст состоит из одной строки, я разбил его ниже для удобства чтения.
Get-Item $vData |`
foreach {`
$_ ; $_ | Get-ChildItem -directory -Force -Recurse `
}`
| foreach {`
$currentDir = $_;`
$acl = ($_ | Get-Acl).Access; `
$IDs = $acl | select identityreference ;`
foreach ($ID in $IDs) { `
if (($ID.ToString()).endswith('-admin')) {`
$acesToRemove = $acl | where{ $_.IsInherited -eq $false -and $_.IdentityReference -eq $ID };`
$acl.RemoveAccessRuleAll($acesToRemove); `
Set-Acl -AclObject $acl $currentDir.ToString(); `
}`
}`
}
Код для удаления разрешений основан на коде, который я нашел здесь Полное удаление пользователя из ACL с помощью PowerShell
решение1
Я считаю, что RemoveAccessRuleAll (и RemoveAccessRule) работают с ACL, а не со свойством Access. Попробуйте что-то вроде этого:
Get-ChidItem -Path $root -Directory -Force -Recurse |
ForEach-Object -Process {
$path = $_.FullName
Write-Output "Working on '$path'"
$acl = Get-Acl -Path $path
if ($aclsToRemove = $acl.Access | Where-Object -FilterScript { $_.IdentityReference -like '*-admin' }) {
Write-Output " Found $($aclsToRemove.Count) ACLs to remove:"
foreach ($aclToRemove in $aclsToRemove) {
Write-Output " Removing $($aclToRemove.IdentityReference) - $($aclToRemove.FileSystemRights) - $($aclToRemove.AccessControlType) from ACL list"
$acl.RemoveAccessRule($aclToRemove)
}
Write-Output " Setting new ACL on filesystem"
Set-Acl -Path $_.FullName -AclObject $acl
}
}
решение2
Нашел ответ ниже на Reddit, и, похоже, он дает то, что мне было нужно.
отhttps://www.reddit.com/r/PowerShell/comments/p19br8/bulk_removing_direct_access_to_a_folder_via/ PS_Алекс
Я думаю, что ваша проблема здесь $acl = ($_ | Get-Acl).Access. Ваш объект $acl содержит только ACE. Командлет Set-Acl ожидает полный объект ACL в качестве входных данных для аргумента -AclObject.
Вместо этого вы можете попробовать это:
#Assuming $vdata is your root path
foreach ($folder in Get-ChildItem -Path $vdata -Directory -Recurse -Force) {
#Get the current ACL of the folder
$acl = Get-Acl -Path $folder.FullName
#Uncomment to explore the $acl object
#$acl | fl
#Filter the ACEs to identify the ones to remove, and remove them
foreach ($aceToRemove in $acl.Access.Where({$psitem.IdentityReference -match "-admin$" -and $psitem.IsInherited -eq $false})) {
$acl.RemoveAccessRule($aceToRemove)
}
#Uncomment to explore the $acl object
#$acl | fl
#Apply the ACL
Set-Acl -AclObject $acl -Path $folder.FullName
}