k-f

Exchange 2003 - ExchangeSetPFADRights.vbs

k-f
Jun 6th, 2011
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. '© Kirill 'kf' Nikolaev, 2011
  2. 'Все вопросы по скрипту: E-mail/Live: [email protected]
  3.  
  4. 'Скрипт раздаёт права на управление объектами общих папок в Active Directory.
  5. 'Основное предназначение — предоставлять гранулированный доступ различным администраторам к общим папкам в пределах одного дерева общих папок. Удобно выполнять по расписанию для проставления нужных разрешений на новые папки.
  6. 'Дополнительно, не забудьте предоставить нужные разрешения администраторам на уровне БД Exchange (кнопка Administrative Rights в св-вах общей папки).
  7.  
  8. 'Папки верхнего ур-ня, на подпапки которых требуется предоставлять доступ, записываются в файл, указанный в переменной strRootFoldersList, по 1 папке на строку в следующем формате:
  9. 'Название общей папки;TEST - то есть: 1) без обрамляющих слешей 2) Через разделитель (strInSplitter) указывается ИМЯ_ФАЙЛА_СО_СПИСКОМ_СУБЪЕКТОВ_БЕЗОПАСНОСТИ.
  10. 'Субъекты безопасности, которым будет предоставлен доступ к объектам общих папок, указываются в соответствующем файле (ИМЯ_ФАЙЛА_СО_СПИСКОМ_СУБЪЕКТОВ_БЕЗОПАСНОСТИ.txt) по одному на строку без каких либо разделителей и т.п.
  11. 'То есть вот так: AD1\Administrators
  12.  
  13. 'Как вы можете видеть, в этом скрипте присутствует обёртка, которая позволяет корректно выполнять его в кластерном окружении по расписанию. Вы можете использовать её в любом скрипте.
  14. 'Посмотреть и скачать обёртку отдельно вы можете здесь: http://pastebin.com/8KPpmf6P
  15.  
  16. strManageComputer = "EXCHANGE-SERVER" 'Имя Exchange-сервера, к которому будем подключаться.
  17. strInFolder = "C:\Scripts\ExchangeSetPFADRights" 'Папка входящих данных. В ней расположены strRootFoldersList и ФАЙЛЫ_СО_СПИСКАМИ_СУБЪЕКТОВ_БЕЗОПАСНОСТИ.txt
  18. strOutFolder = strInFolder 'Папка исходящих данных. В ней расположен strResFile.
  19. strResFile = strOutFolder & "\" & WScript.ScriptName & ".txt"
  20. strRootFoldersList = strInFolder & "\RootFoldersList.txt"
  21. strSplitter = ";" 'Разделитель колонок в логе
  22. strInSplitter = strSplitter 'Разделитель колонок в файлах входящих данных.
  23. strClusResource = "EXCHANGE-SERVER Network Name" 'Кластерный ресурс, на владельце которого будет выполняться скрипт.
  24.  
  25. Set wshNetwork = WScript.CreateObject("WScript.Network")
  26. strComputerName = wshNetwork.ComputerName
  27.  
  28. Set objCluster = CreateObject("MSCluster.Cluster")
  29. objCluster.Open strManageComputer
  30.  
  31. If objCluster.Resources.Item(strClusResource).OwnerNode.Name = strComputerName Then 'Проверяем, что текущий компьютер является владельцем нужного кластерного ресурса.
  32.  
  33.     Set FSO = CreateObject("Scripting.FileSystemObject")
  34.     Set ResFile = FSO.OpenTextFile(strResFile, 2, True)
  35.  
  36.     Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strManageComputer & "\ROOT\MicrosoftExchangeV2")
  37.     Set colItems = objWMIService.InstancesOf("Exchange_PublicFolder")
  38.  
  39.     For Each objItem in colItems
  40.         Set RootFoldersList = FSO.OpenTextFile(strRootFoldersList, 1)
  41.         Do While RootFoldersList.AtEndOfLine <> True
  42.             strLine = RootFoldersList.ReadLine()
  43.             strRootFolderDividerPosition = InStr(strLine, strInSplitter)
  44.             strRootFolderName = Left(strLine, strRootFolderDividerPosition-1)
  45.             strRootFolderPath = "/" & strRootFolderName & "/"
  46.             strRootFolderTrusteeList = strInFolder & "\" & Right(strLine, Len(strLine)-strRootFolderDividerPosition) & ".txt"
  47.             strFolderPath = objItem.Path
  48.             If InStr(strFolderPath, strRootFolderPath) = 1 Then
  49.                 strResFileLine = strFolderPath
  50.                 strFullWebDAVPath = objItem.FriendlyUrl
  51.                 XMLSettingValue = GetXMLSettingValue (strFullWebDAVPath, "671D0102")
  52.                 If VarType(XMLSettingValue) = 8209 Then 'Проверяем, mail-enabled-ли папка? На не-mail-enabled дальнейшие действия смысла выполнять нет, да и невозможно это.
  53.                     strFolderGUID = OctetToHexStr(XMLSettingValue)
  54.                     strFolderEncodedGUID = GenerateGUIDForLDAPSearch(strFolderGUID)
  55.                     Set objFolderADObject = GetObject(FindADObject("objectGUID", strFolderEncodedGUID))
  56.                     strFolderMail = objFolderADObject.Get("mail")
  57.                     Set FolderTrusteeList = FSO.OpenTextFile(strRootFolderTrusteeList, 1)
  58.                     Do While FolderTrusteeList.AtEndOfLine <> True
  59.                         strTrustee = FolderTrusteeList.ReadLine()
  60.                         SetFolderADACL objFolderADObject, strTrustee
  61.                         strResFileLine = strResFileLine & strSplitter & strTrustee
  62.                     Loop
  63.                     FolderTrusteeList.Close
  64.                     ResFile.WriteLine strResFileLine
  65.                 End If
  66.             End If
  67.         Loop
  68.         RootFoldersList.Close
  69.     Next
  70.  
  71.     ResFile.Close
  72. End If
  73. 'Wscript.Echo WScript.ScriptName & " Done" 'Полезно в интерактивном режиме, но мешает при выполнении по расписанию.
  74.  
  75. Function SetFolderADACL (objFolderADObject, strTrustee) 'Собственно, назначает разрешения.
  76.  
  77.     Const ADS_OPTION_SECURITY_MASK = 3 'http://support.microsoft.com/kb/323749
  78.     Const ADS_SECURITY_INFO_DACL = 4 'http://support.microsoft.com/kb/323749
  79.     Const ADS_ACETYPE_ACCESS_ALLOWED = &H0 'The ACE is of the standard ACCESS ALLOWED type, where the ObjectType and InheritedObjectType fields are NULL
  80.  
  81.     Set objFolderSD = objFolderADObject.Get("ntSecurityDescriptor")
  82.     Set objFolderDACL = objFolderSD.DiscretionaryAcl
  83.     Set objAce = CreateObject("AccessControlEntry")
  84.  
  85.     objAce.AccessMask = -1 'Full Permission (Allowed)
  86.     objAce.AceType = ADS_ACETYPE_ACCESS_ALLOWED
  87.     objAce.AceFlags = &H2 'This object and subcontainers
  88.     objAce.Trustee = strTrustee
  89.  
  90.     objFolderDACL.AddAce objAce
  91.  
  92.     objFolderSD.DiscretionaryAcl = objFolderDACL
  93.     objFolderADObject.Put "ntSecurityDescriptor", objFolderSD
  94.     objFolderADObject.SetOption ADS_OPTION_SECURITY_MASK, ADS_SECURITY_INFO_DACL 'http://support.microsoft.com/kb/323749
  95.     objFolderADObject.SetInfo
  96.  
  97. End Function
  98.  
  99. Function GetXMLSettingValue (strFullWebDAVPath, strSetting) 'Получает значение св-ва общей папки по WebDAV.
  100.     Dim strRequest
  101.     Set objXML = CreateObject("msxml2.xmlhttp")
  102.     objXML.Open "PROPFIND", strFullWebDAVPath, FALSE
  103.     objXML.SetRequestHeader "Content-type:", "text/xml"
  104.     objXML.SetRequestHeader "Depth", "0"
  105.     strRequest = "<?xml version='1.0'?>"
  106.     strRequest = strRequest & "<a:propfind xmlns:a='DAV:' xmlns:p='http://schemas.microsoft.com/mapi/proptag/'>"
  107.     strRequest = strRequest & "<a:prop><p:x" & strSetting & "/></a:prop>"
  108.     strRequest = strRequest & "</a:propfind>"
  109.     objXML.send strRequest
  110.     Dim objNodeList
  111.     Set objNodeList = objXML.responseXML.getElementsByTagName("d:x" & strSetting)
  112.     For i = 0 to (objNodeList.length-1)
  113.         Set objNode = objNodeList.nextNode
  114.     Next
  115.     GetXMLSettingValue = objNode.nodeTypedValue
  116. End Function
  117.  
  118. Function OctetToHexStr (arrbytOctet)
  119. ' Function to convert OctetString (byte array) to Hex string.
  120. ' Code from Richard Mueller, a MS MVP in Scripting and ADSI
  121.     Dim k
  122.     OctetToHexStr = ""
  123.     For k = 1 To Lenb (arrbytOctet)
  124.         OctetToHexStr = OctetToHexStr & Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2)
  125.     Next
  126. End Function
  127.  
  128. Function FindADObject (strParameter, strValue) 'Ищет объект общей папки в AD.
  129.     'On Error Resume Next
  130.  
  131.     set cn = createobject("ADODB.Connection")
  132.     set cmd = createobject("ADODB.Command")
  133.     set rs = createobject("ADODB.Recordset")
  134.  
  135.     cn.open "Provider=ADsDSOObject;"
  136.    
  137.     cmd.activeconnection=cn
  138.     cmd.commandtext="SELECT ADsPath FROM 'LDAP://ad1.example.com' WHERE " & strParameter & " = '" & strValue & "'"
  139.    
  140.     set rs = cmd.execute
  141.  
  142.     if err<>0 then
  143.         FindADObject="Error connecting to Active Directory Database:" & err.description
  144.     else
  145.         if not rs.BOF and not rs.EOF then
  146.                 rs.MoveFirst
  147.                 FindADObject = rs(0)
  148.         else 'У меня всего 2 домена, поэтому так грязно. Перепишите, кто-нибудь :)
  149.             cmd.commandtext="SELECT ADsPath FROM 'LDAP://ad2.example.com' WHERE " & strParameter & " = '" & strValue & "'"
  150.             set rs = cmd.execute
  151.             if err<>0 then
  152.                 FindADObject="Error connecting to Active Directory Database:" & err.description
  153.             else
  154.                 if not rs.BOF and not rs.EOF then
  155.                     rs.MoveFirst
  156.                     FindADObject = rs(0)
  157.                 else
  158.                     FindADObject = "Not Found"
  159.                 End If
  160.             End If
  161.         end if
  162.     end if
  163.     cn.close
  164.  
  165. End Function
  166.  
  167. Function GenerateGUIDForLDAPSearch (strGUID) 'Возвращает строку для поиска общей папки при помощи ф-ии FindADObject
  168.     Counter = 0
  169.     strRes = "\" & Left(strGUID, 2)
  170.     For Counter = 1 To 15
  171.         strTail = Right(strGUID, Len(strGUID)-(Counter*2))
  172.         strPiece = Left (strTail, 2)
  173.         strRes = strRes & "\" & strPiece
  174.     Next
  175.     GenerateGUIDForLDAPSearch = strRes
  176. End Function
Advertisement
Add Comment
Please, Sign In to add comment