Тема: VBS: Отключить наследование NTFS у сетевой папки (файла)
Доброго времени суток!
Задача.
Почистить список acl ntfs у сетевой папки.
Есть код:
Option Explicit
Call ClearACL()
Sub ClearACL()
Const ADS_PATH_FILE = 1
Const ADS_SD_FORMAT_IID = 1
Dim sFile, oADsSecurityUtility, oSD, oDacl, oAce
sFile = "\\fileserver\Documents\testfolder"
Set oADsSecurityUtility = CreateObject("ADsSecurityUtility")
Set oSD = oADsSecurityUtility.GetSecurityDescriptor(sFile, ADS_PATH_FILE, ADS_SD_FORMAT_IID)
Set oDacl = oSD.DiscretionaryAcl
For Each oAce In oDacl
if (InStr(oAce.Trustee, "Administrators") = 0) and (InStr(oAce.Trustee, "SYSTEM") = 0) and _
(InStr(oAce.Trustee, "Администраторы") = 0) and (InStr(oAce.Trustee, "СИСТЕМА") = 0) then
oDacl.RemoveAce oAce
End If
Next
oSD.DiscretionaryAcl = oDacl
oADsSecurityUtility.SetSecurityDescriptor sFile, ADS_PATH_FILE, oSD, ADS_SD_FORMAT_IID
end Sub
Он работает, на windows xp, windows 7 - удаляются все лишние acl, при этом наследование выключается автоматически.
А вот на 2012r2 наследование автоматом не выключается и унаследованные группы не удаляются. Если выключить наследование вручную (снять галочку в свойствах папки),
то скрипт отрабатывает как и положено.
Я подумал, что проблему можно решить просто - снять наследование, а затем уже удалять acl.
Решил пойти по пути наименьшего сопротивления и написал процедуру, использующую wmi, как в соседних темах в примерах:
Option Explicit
Call DisableInheritanceWMI()
Sub DisableInheritanceWMI()
Const SE_DACL_PROTECTED = 4096
Dim sFile, oWMI, oSec, oSD
sFile = "u:\Documents\testfolder"
On Error Resume Next
Set oWMI = GetObject("WinMgmts:\\.")
If Err.Number <> 0 Then MsgBox "Ошибка " & CStr(Err.Number) & vbNewLine & Err.Description : Wscript.Exit
Set oSec = oWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & sFile & "'")
If Err.Number <> 0 Then MsgBox "Ошибка2 " & CStr(Err.Number) & vbNewLine & Err.Description : Wscript.Exit
If oSec.GetSecurityDescriptor(oSD) <> 0 Then MsgBox "Не удалось прочитать дескриптор безопасности каталога " & UCase(strDir) : Wscript.Exit
If Not CBool(oSD.ControlFlags And SE_DACL_PROTECTED) Then
oSD.ControlFlags = oSD.ControlFlags + SE_DACL_PROTECTED
If oSec.SetSecurityDescriptor(oSD) <> 0 Then MsgBox "Не удалось применить настройки" : Wscript.Exit
End If
End Sub
Процедура работает, но только с локальными папками.
Заставить её работать с сетевой к сожалению не удалось.
Я не сдался и попробовал сделать иначе:
Вот третья процедура, которая должна выключать наследование, перед запуском первой:
Option Explicit
Call DisableInheritance()
Sub DisableInheritance()
Const ADS_PATH_FILE = 1
Const ADS_SD_FORMAT_IID = 1
Const SE_DACL_PROTECTED = 4096
Dim sFile, oADsSecurityUtility, oSD
sFile = "\\fileserver\Documents\testfolder"
Set oADsSecurityUtility = CreateObject("ADsSecurityUtility")
Set oSD = oADsSecurityUtility.GetSecurityDescriptor(sFile, ADS_PATH_FILE, ADS_SD_FORMAT_IID)
oSD.Control = oSD.Control + SE_DACL_PROTECTED
oADsSecurityUtility.SetSecurityDescriptor sFile, ADS_PATH_FILE, oSD, ADS_SD_FORMAT_IID
End Sub
И вот, вроде бы всё должно работать, но к сожалению нет.
Такое ощущение, что галочка снимается, acl переделываются в неунаследованные,
а после галка мгновенно ставится на место.
Ребята, подскажите, что я делаю не так или что не то сделала Microsoft с vbs в 2012r2?