none
Скрипт для измения списка ACL папок RRS feed

  • Вопрос

  • Добрый день. коллеги.

     

    Имеется папка, содержащая много других папок, и в списках ACL этих папок присутствуют давно удаленные юзеры типа(S-1-5-21-2813971328-4228728021-3007165431-3610). Можно как то из всех спсиков ACL, содержащих такие объекты их удалить волшебным скриптом?

     

Ответы

  • Можно как то из всех спсиков ACL, содержащих такие объекты их удалить волшебным скриптом?

    Вариант на VBS для GUI:

     

    Dim objShell, objFolder, objWShell, strComputer, strPath
    Dim objWMI, objSecSettings, objSD, objACE
    Dim blnHasProtected, blnHasError, intResult, strLog, arrACE, strTemp
    Const INHERITED_ACE = 16
    Const SE_DACL_PROTECTED = 4096
    
    strComputer = "."
    strLog = "Clear_DACL.log"
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Выбор каталога", &h10 + &h200, &h11)
    If Not objFolder Is Nothing Then
    	Set objFS = CreateObject("Scripting.FileSystemObject")
    	strLog = objFS.BuildPath(objFS.GetParentFolderName(WScript.ScriptFullName), strLog)
     	Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    	strPath = objFolder.Self.Path
    	For Each objItem In objFS.GetFolder(strPath).SubFolders
    		blnHasError = False
    		strTemp = strTemp & UCase(objItem.Path) & vbNewLine
    		Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & objItem.Path & "'")
    		If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
    			intResult = 0
    			If Not IsNull(objSD.DACL) Then
    				If CBool(objSD.ControlFlags And SE_DACL_PROTECTED) Then
    					blnHasProtected = True
    					arrACE = objSD.DACL
    				Else
    					arrACE = Array()
    					i = -1
    					For Each objACE In objSD.DACL
    						If Not CBool(objACE.AceFlags And INHERITED_ACE) Then
    							i = i + 1
    							ReDim Preserve arrACE(i)
    							Set arrACE(i) = objACE
    						Else
    							If IsNull(objACE.Trustee.Name) Then
    								blnHasError = True
    								strTemp = strTemp & "Запись " & objACE.Trustee.SIDString & " унаследована от ""родителя""." & vbNewLine
    							End If
    						End If
    					Next
    					objSD.ControlFlags = objSD.ControlFlags + SE_DACL_PROTECTED
    					intResult = objSecSettings.SetSecurityDescriptor(objSD)
    				End If
    				If intResult = 0 Then
    					For Each objACE In arrACE
    						If IsNull(objACE.Trustee.Name) Then
    							objACE.AccessMask = 0
    						End If
    					Next
    					Set objACE = Nothing
    					objSD.DACL = arrACE
    					Erase arrACE
    					If Not blnHasProtected Then
    						objSD.ControlFlags = objSD.ControlFlags - SE_DACL_PROTECTED
    					End If
    					intResult = objSecSettings.SetSecurityDescriptor(objSD)
    					Select Case intResult
    						Case "0": If Not blnHasError Then strTemp = strTemp & "Успешное завершение." & vbNewLine
    						Case "2": strTemp = strTemp & "Доступ запрещён." & vbNewLine
    						Case "5", "9": strTemp = strTemp & "Для выполнения операции недостаточно полномочий." & vbNewLine
    						Case "21": strTemp = strTemp & "Заданы недопустимые значения параметров." & vbNewLine
    						Case Else: strTemp = strTemp & "Неизвестная ошибка с кодом: " & intResult & vbNewLine
    					End Select
    				Else
    					strTemp = strTemp & "Не удалось отключить наследование безопасности." & vbNewLine
    				End If
    			Else
    				strTemp = strTemp & "Список управления доступом пуст." & vbNewLine
    			End If
    		Else
    			strTemp = strTemp & "Не удалось прочитать дескриптор безопасности." & vbNewLine
    		End If
    		Set objSD = Nothing
    		Set objSecSettings = Nothing
    		strTemp = strTemp & vbNewLine
    	Next
    	Set objItem = Nothing
    	Set objWMI = Nothing
    	Set objFile = objFS.OpenTextFile(strLog, 2, True)
    	objFile.Write strTemp
    	objFile.Close
    	Set objFS = Nothing
    	Set objWShell = CreateObject("WScript.Shell")
    	objWShell.Run "notepad.exe " & strLog, 1
    	Set objWShell = Nothing
    End If
    Set objFolder = Nothing
    Set objShell = Nothing
    WScript.Quit 0
    

     

  • Проверок никаких не делалось,так же берется корень папки.

     

    PS 30 #  Remove-TempSid F:\test\ -Verbose
    
    VERBOSE: Получаем Acl - F:\test\
    VERBOSE: Удаляем правило с Sid - S-1-5-21-3033362042-1573752120-755305396-1049 - F:\test\
    VERBOSE: Обновляем Acl - F:\test\
    VERBOSE: Получаем Acl - F:\test\otdel1
    VERBOSE: Получаем Acl - F:\test\otdel1\New folder
    

     

    Function Remove-TempSid
    {
    	[CmdletBinding()]
    	param([Parameter(Mandatory=$true,
          ValueFromPipeline=$true)]
    		  [string]
    		  [ValidateScript({Test-Path $_ })]
    		  $Path
    		 )
    	
    	$folders = @(Get-Item $Path;Get-ChildItem $Path -Force -Recurse | Where {$_.PsIsContainer})
    	foreach ($f in $folders)
    	{
    		Write-Verbose "Получаем Acl - $($f.fullname)"
    		$acl = Get-Acl $f.fullname
    		$acl.Access | Where {$_.IdentityReference -match "S-1-"} | Foreach {
    			if($_.IsInherited)
    			{
    				Write-Host "Объект $($_.IdentityReference) унаследован от родителя"
    			}
    			else 
    			{
    				Write-Verbose "Удаляем правило с Sid - $($_.IdentityReference) - $($f.fullname) "
    				$acl.RemoveAccessRule($_) | Out-Null
    				Write-Verbose "Обновляем Acl - $($f.fullname)"
    				$acl | Set-Acl -Path $f.fullname 
    			}		
    		}
    	}
    }
    

    Отвечающий

Все ответы

  • например subinacl может удалить
  • Можно как то из всех спсиков ACL, содержащих такие объекты их удалить волшебным скриптом?

    Вариант на VBS для GUI:

     

    Dim objShell, objFolder, objWShell, strComputer, strPath
    Dim objWMI, objSecSettings, objSD, objACE
    Dim blnHasProtected, blnHasError, intResult, strLog, arrACE, strTemp
    Const INHERITED_ACE = 16
    Const SE_DACL_PROTECTED = 4096
    
    strComputer = "."
    strLog = "Clear_DACL.log"
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.BrowseForFolder(0, "Выбор каталога", &h10 + &h200, &h11)
    If Not objFolder Is Nothing Then
    	Set objFS = CreateObject("Scripting.FileSystemObject")
    	strLog = objFS.BuildPath(objFS.GetParentFolderName(WScript.ScriptFullName), strLog)
     	Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    	strPath = objFolder.Self.Path
    	For Each objItem In objFS.GetFolder(strPath).SubFolders
    		blnHasError = False
    		strTemp = strTemp & UCase(objItem.Path) & vbNewLine
    		Set objSecSettings = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & objItem.Path & "'")
    		If objSecSettings.GetSecurityDescriptor(objSD) = 0 Then
    			intResult = 0
    			If Not IsNull(objSD.DACL) Then
    				If CBool(objSD.ControlFlags And SE_DACL_PROTECTED) Then
    					blnHasProtected = True
    					arrACE = objSD.DACL
    				Else
    					arrACE = Array()
    					i = -1
    					For Each objACE In objSD.DACL
    						If Not CBool(objACE.AceFlags And INHERITED_ACE) Then
    							i = i + 1
    							ReDim Preserve arrACE(i)
    							Set arrACE(i) = objACE
    						Else
    							If IsNull(objACE.Trustee.Name) Then
    								blnHasError = True
    								strTemp = strTemp & "Запись " & objACE.Trustee.SIDString & " унаследована от ""родителя""." & vbNewLine
    							End If
    						End If
    					Next
    					objSD.ControlFlags = objSD.ControlFlags + SE_DACL_PROTECTED
    					intResult = objSecSettings.SetSecurityDescriptor(objSD)
    				End If
    				If intResult = 0 Then
    					For Each objACE In arrACE
    						If IsNull(objACE.Trustee.Name) Then
    							objACE.AccessMask = 0
    						End If
    					Next
    					Set objACE = Nothing
    					objSD.DACL = arrACE
    					Erase arrACE
    					If Not blnHasProtected Then
    						objSD.ControlFlags = objSD.ControlFlags - SE_DACL_PROTECTED
    					End If
    					intResult = objSecSettings.SetSecurityDescriptor(objSD)
    					Select Case intResult
    						Case "0": If Not blnHasError Then strTemp = strTemp & "Успешное завершение." & vbNewLine
    						Case "2": strTemp = strTemp & "Доступ запрещён." & vbNewLine
    						Case "5", "9": strTemp = strTemp & "Для выполнения операции недостаточно полномочий." & vbNewLine
    						Case "21": strTemp = strTemp & "Заданы недопустимые значения параметров." & vbNewLine
    						Case Else: strTemp = strTemp & "Неизвестная ошибка с кодом: " & intResult & vbNewLine
    					End Select
    				Else
    					strTemp = strTemp & "Не удалось отключить наследование безопасности." & vbNewLine
    				End If
    			Else
    				strTemp = strTemp & "Список управления доступом пуст." & vbNewLine
    			End If
    		Else
    			strTemp = strTemp & "Не удалось прочитать дескриптор безопасности." & vbNewLine
    		End If
    		Set objSD = Nothing
    		Set objSecSettings = Nothing
    		strTemp = strTemp & vbNewLine
    	Next
    	Set objItem = Nothing
    	Set objWMI = Nothing
    	Set objFile = objFS.OpenTextFile(strLog, 2, True)
    	objFile.Write strTemp
    	objFile.Close
    	Set objFS = Nothing
    	Set objWShell = CreateObject("WScript.Shell")
    	objWShell.Run "notepad.exe " & strLog, 1
    	Set objWShell = Nothing
    End If
    Set objFolder = Nothing
    Set objShell = Nothing
    WScript.Quit 0
    

     

  • Я забыл сказать, я имел ввиду на Powershell скрипт, я в висуале не але. Но за ответ спасибо.
  • Проверок никаких не делалось,так же берется корень папки.

     

    PS 30 #  Remove-TempSid F:\test\ -Verbose
    
    VERBOSE: Получаем Acl - F:\test\
    VERBOSE: Удаляем правило с Sid - S-1-5-21-3033362042-1573752120-755305396-1049 - F:\test\
    VERBOSE: Обновляем Acl - F:\test\
    VERBOSE: Получаем Acl - F:\test\otdel1
    VERBOSE: Получаем Acl - F:\test\otdel1\New folder
    

     

    Function Remove-TempSid
    {
    	[CmdletBinding()]
    	param([Parameter(Mandatory=$true,
          ValueFromPipeline=$true)]
    		  [string]
    		  [ValidateScript({Test-Path $_ })]
    		  $Path
    		 )
    	
    	$folders = @(Get-Item $Path;Get-ChildItem $Path -Force -Recurse | Where {$_.PsIsContainer})
    	foreach ($f in $folders)
    	{
    		Write-Verbose "Получаем Acl - $($f.fullname)"
    		$acl = Get-Acl $f.fullname
    		$acl.Access | Where {$_.IdentityReference -match "S-1-"} | Foreach {
    			if($_.IsInherited)
    			{
    				Write-Host "Объект $($_.IdentityReference) унаследован от родителя"
    			}
    			else 
    			{
    				Write-Verbose "Удаляем правило с Sid - $($_.IdentityReference) - $($f.fullname) "
    				$acl.RemoveAccessRule($_) | Out-Null
    				Write-Verbose "Обновляем Acl - $($f.fullname)"
    				$acl | Set-Acl -Path $f.fullname 
    			}		
    		}
    	}
    }
    

    Отвечающий
  • Ну Вы монстр Kazun!) На любом языке, я попробую на днях, отпишусь, спасибо.