Pull to refresh

Опытные мелочи-5, или «Групповые радости!»

Reading time 7 min
Views 18K
image Продолжение «опытных мелочей». Предыдущие части: раз, два, три, четыре.

В этом посте поговорим о группах в Active Directory. Я не буду вдаваться глубоко в теорию и рассказывать об универсальных, глобальных локальных группах — желающие все подробности смогут найти в документации, благо ее предостаточно. Поговорим о том, зачем вообще бывают нужны группы и о какие «вкусности», можно получить с их помощью.


  • Используйте группы везде, где можете, вместо отдельных пользователей. В ACL, разрешениях, выдаче прав, групповой политике и т.д. Даже если в группе сейчас только один человек — все равно, используйте группы. Это не только ускоряет работу системы (например ACL из 2-3 групп и ACL из 15 пользователей обрабатываются совсем не одинаково по времени), но и в дальнейшем сильно облегчит управление. Вам не потребуется вспоминать где и как вы назначали то или иное право, у вас будет единая консоль ActiveDirectory, в которой вы просто добавите нового человека, или удалите старого из группы, и все. Настройка завершена.
  • Называйте группы осмысленно, пишите подробную информацию в Description, используйте префиксы. Например группы которые используются для разрешения доступа к папкам можно называть так FLD_FolderName_RW, а группы доступа в интернет I_FullAccess. Префикс позволит быстро находить группы в AD (жмете добавить пользователя в группу, и по префиксу сразу находится список именно тех групп, которые вы ищете). Осмысленное название и описание в Description позволит вам (или уже не вам) через полгода\год\ит.д. вспомнить смысл, который вы вкладывали в созданную группу.
  • Не увлекайтесь вложенными группами. Это полезная вещь, но если переусердствовать, то можно прийти к циклической вложенности и сами себя запутаете.
  • Делегируйте управление группами. Вынесите все ваши группы в отдельное структурированное OU и делегируйте права на управление членством в группах тем, кто за это отвечает. Например принимать у нас делегировано управление доступом в папки секретарям, а управление разрешением на удаленный доступ — в СБ. Вся волокита по «напиши служебку — подпиши ее у ответственного — ок вот мы тебя добавили — вот тебе инструкция — служебку в архив» передана им, и часть рутины ушла из отдела ИТ.
  • Используйте группы творчески, например для назначения каких либо привилегий, раздачи принтеров, раскладывания ярлыков на рабочих столах, прописывание баз 1С с помощью логон-скриптов и т.д. Учитывая, что группа в AD это довольно «емкий» объект, можно хранить прямо в них различные настройки, параметры — передаваемые скрипту при выполнении. Логика работы таких скриптов такова:
    1. Скрипт определяет в каких группах состоит данный пользователь
    2. Выбирает конкретные группы по заранее определенному признаку (например по префиксу!)
    3. Вытаскивает из этих групп «параметры» (поле Description, название группы без префикса и т.д.) и запускает внешнюю команду, или процедуру с этими параметрами

В качестве примера приведу скрипт, который работает по этому принципу: определяет в каких группах состоит пользователь, находит среди них группы с префиксом RDP_, и создает у человека RDP-ярлык на рабочем столе с следующими параметрами:
  • Название ярлыка равно названию группы без префикса,
  • имя целевого сервера, на который ссылается RDP-ярлык записано в Description группы.
В результате, чтобы пустить кого-то на сервер 1С, достаточно добавить его в группу, и попросить перезайти в систему. Кроме всего прочего на бухгалтерском терминальном сервере удаленный доступ разрешен только Администраторам и членам групп RDP_GroupName.

' Скрипт создает на рабочем столе пользователя RDP-ярлык удаленного подключения, базируясь на членстве в группах.
' Шаблон названия группы - RDP_НазваниеЯрлыка в поле Description указываем имя сервера, на который настраивается RDP-соединение
' например AD-группа RDP_1C-Бухгалтерия с описанием Server1.domain.local в поле Desription
' Если ярлык с таким названием уже есть - он пересоздается, что решает задачу обновления параметров.
' при необходимости параметры RDP-файла можно поправить в теле скрипта.
On Error Resume Next
Set wshShell = WScript.CreateObject("WScript.Shell")
Set m_FSO = CreateObject("Scripting.FileSystemObject")

' Находим пользователя в AD и определем его параметры
Set objSysInfo = CreateObject("ADSystemInfo")
ADSPath = "LDAP://" & objSysInfo.UserName
Set objUser = GetObject(ADSPath)
ShortUserName = objUser.SamAccountName
DomainName = objSysInfo.DomainShortName

' Читаем путь к Рабочему столу
DesktopPath = wshShell.SpecialFolders("Desktop")
LevelCount = 0
MaxLevelCount = 4
Status = CheckGroups(ADSPath)

' дальше идет нудный перечень используемых функций
'============ Function GetPrefixNameGroup ============
Function GetPrefixNameGroup(sString)
' Trim prefix of name group
Dim TempString
TempString = Left(sString, InStr(sString, "_"))
GetPrefixNameGroup = TempString
End Function
'=====================================================
'============ Function GetLinkNameGroup ============
Function GetLinkNameGroup(sString)
' Trim LinkName of name group
Dim TempString
TempString = Mid(sString, InStrRev(sString, "_")+1)
GetLinkNameGroup = TempString
End Function
'=====================================================
'============ Function Create RdpFile ============
Function CreateRDPFile(sString, sName)
spath = DesktopPath & "\" & sString & ".rdp"
' проверяем наличие такого же файла - если есть - удаляем его'
If m_FSO.FileExists(sPath) or m_FSO.FolderExists(sPath) Then
m_FSO.DeleteFile (sPath),1
End If
Set RDPFile = m_FSO.CreateTextFile (spath, True)
RDPFile.writeline ("screen mode id:i:2")
RDPFile.writeline ("use multimon:i:0")
RDPFile.writeline ("desktopwidth:i:1280")
RDPFile.writeline ("desktopheight:i:1024")
RDPFile.writeline ("session bpp:i:16")
RDPFile.writeline ("winposstr:s:0,1,0,0,800,600")
RDPFile.writeline ("compression:i:1")
RDPFile.writeline ("keyboardhook:i:2")
RDPFile.writeline ("audiocapturemode:i:0")
RDPFile.writeline ("videoplaybackmode:i:1")
RDPFile.writeline ("connection type:i:2")
RDPFile.writeline ("displayconnectionbar:i:1")
RDPFile.writeline ("disable wallpaper:i:1")
RDPFile.writeline ("disable full window drag:i:1")
RDPFile.writeline ("allow desktop composition:i:0")
RDPFile.writeline ("allow font smoothing:i:0")
RDPFile.writeline ("disable menu anims:i:1")
RDPFile.writeline ("disable themes:i:1")
RDPFile.writeline ("disable cursor setting:i:0")
RDPFile.writeline ("bitmapcachepersistenable:i:1")
' добавление имени сервера '
RDPFile.writeline ("full address:s:" & sName)
RDPFile.writeline ("audiomode:i:2")
RDPFile.writeline ("redirectprinters:i:0")
RDPFile.writeline ("redirectcomports:i:0")
RDPFile.writeline ("redirectsmartcards:i:0")
RDPFile.writeline ("redirectclipboard:i:1")
RDPFile.writeline ("redirectposdevices:i:0")
RDPFile.writeline ("redirectdirectx:i:1")
RDPFile.writeline ("autoreconnection enabled:i:1")
RDPFile.writeline ("authentication level:i:0")
RDPFile.writeline ("prompt for credentials:i:0")
RDPFile.writeline ("negotiate security layer:i:1")
RDPFile.writeline ("remoteapplicationmode:i:0")
RDPFile.writeline ("alternate shell:s:")
RDPFile.writeline ("shell working directory:s:")
RDPFile.writeline ("gatewayhostname:s:")
RDPFile.writeline ("gatewayusagemethod:i:4")
RDPFile.writeline ("gatewaycredentialssource:i:4")
RDPFile.writeline ("gatewayprofileusagemethod:i:0")
RDPFile.writeline ("promptcredentialonce:i:1")
' добавление имени пользователя в нотации Domain\Username'
RDPFile.writeline ("username:s:" & DomainName& "\"& ShortUserName)
RDPFile.writeline ("drivestoredirect:s:")
RDPFile.close
End Function
'=====================================================
'============ Function CheckGroups ===================
Function CheckGroups(ADSPath)
Dim objUser, arrMemberOf
Const E_ADS_PROPERTY_NOT_FOUND = &h8000500D
LevelCount = LevelCount + 1
if ( LevelCount >= MaxLevelCount) then
LevelCount = LevelCount - 1
return LevelCount
end If
Set objUser = GetObject (ADSPath)
On Error Resume Next
arrMemberOf = objUser.GetEx("memberOf")
If Err.Number = E_ADS_PROPERTY_NOT_FOUND Then
LevelCount = LevelCount - 1
return LevelCount
Else
For Each Group in arrMemberOf
ADSGroup = "LDAP://" & Group
CheckGroups(ADSGroup)
WScript.Echo "Extra=" & LevelCount
Set objGroup = GetObject ( ADSGroup )
If(GetPrefixNameGroup(objGroup.CN) = "RDP_") Then
Set objGroup = GetObject ( "LDAP://" & Group)
LinkName = GetLinkNameGroup(objGroup.CN)
LinkServer = objGroup.description
LinkResult = CreateRDPFile (LinkName, LinkServer)
end If
Next
End If
LevelCount = LevelCount - 1
End Function
'=====================================================

А, чтоб не повторятся простыней скрипта, и вдобавок для разжигания «праведного любопытства сисадмина» примером номером два пойдет скриншот из AD.
image
Здесь используется аналогичный скрипт для добавления пользователям баз 1С. Причем, как нетрудно догадаться, с частью баз пользователи работают в терминале (в двух разных) и скрипт добавления путей запускается на самом терминале, поэтому пути локальные. С другой частью баз (зарплатные) — через сеть, и скрипт запускается на рабочих станциях, что в общем то неважно, ему все равно какие пути добавлять пользователю. Если будете сами делать подобное — не забывайте, что в 1С7.7 и в 1С8.Х — разные принципы добавления путей к базам, соответственно нужны либо разные скрипты, либо две разные функции в теле скрипта.
А еще лучше прямо запуск самой 1С делать через такой скрипт, который сначала пропишет все что нужно, а потом запустит программу.

Продолжение следует

P.S. подскажите пож. Как на Хабре лучше выкладывать скрипты и вообще код, а то больно длинный пост получается.
Tags:
Hubs:
+19
Comments 23
Comments Comments 23

Articles