Advertisement
hdablin

Модуль сценария ADT "CM_ActiveDirectory"

Dec 4th, 2012
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #===============<Модуль ActiveDirectory: константы>===============
  2.  
  3. #Код ошибки "Подразделение AD с заданным именем уже существует"
  4. Set-Constant -Name "SYSTEM_ERROR_CODE_OU_ALREADY_EXISTS" -Value -2147019886
  5.  
  6. #------Код ошибки: объект с заданным именем уже существует.
  7. Set-Constant -Name "SYSTEM_ERROR_CODE_OU_ALREADY_EXISTS"  -Value -2147019886
  8. Set-Constant -Name "SYSTEM_ERROR_CODE_GPO_LINK_ALREADY_EXISTS"  -Value "0x800700B7"
  9.  
  10. #===============</Модуль ActiveDirectory: константы>===============
  11.  
  12. #------Псевдодимы разрешений (прав доступа) к объектам групповых политик.
  13. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_READ" -Value   "read"  
  14. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_EDIT" -Value           "edit"  
  15. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_APPLY"  -Value "Apply Group Policy"  
  16. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_FULL_EDIT"  -Value     "fulledit"  
  17. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_NONE"   -Value         "none"  
  18. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_WRITE"  -Value         "Write"  
  19. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_CREATE_ALL_CHILD_OBJECT"    -Value     "Create All Child Object"  
  20. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_DELETE_ALL_CHILD_OBJECT"    -Value     "Delete All Child Object"  
  21. Set-Constant -Name "SYSTEM_AD_GPO_PERMISSION_FULL_CONTROL"   -Value     "Full Control"
  22.  
  23.  
  24. #===============<Модуль ActiveDirectory: функции>==================
  25.  
  26. <#
  27. .SYNOPSIS
  28.     Принимает путь к OU в формате "example.com/123/456", возвращает его Distinguished Name.
  29.    
  30. .Description
  31.     Корректность пути и его существование не проверяется, что позвоялет использовать функцию
  32.     для несуществующих путей.
  33.     ВНИМАНИЕ: имя домена должно быть полным DNS-именем, а не NEIBIOS именем (т.е. example.com, а не EXAMPLE)
  34.    
  35. .PARAMETER Path
  36.     Путь, который будет сконвертирован в DN
  37.  
  38. .OUTPUTS   
  39.     System.String. Возвращает Distinguished Name, соответствующий переданному пути.
  40. #> 
  41. Function Convert-ADPath2DN([STRING]$Path)
  42. {   $Res = ""
  43.     $ResOU = $null
  44.     #Преобразуем путь к OU в OU DN
  45.     $P = Join-Path $Path "/"
  46.     $P = $P.Replace("\","/")
  47.     #Проверяем, получилось ли у нас что-то похожее на путь
  48.     if ($P -match "^(?<DNS_DOMAIN_NAME>(\w+\.\w+)+)\/.+$")
  49.     {
  50.    
  51.    
  52.         $i = 0
  53.         $DNS_DOMAIN_NAME = $Matches.DNS_DOMAIN_NAME    
  54.         #Формируем путь по OU
  55.         While (-not ($P -eq $DNS_DOMAIN_NAME))
  56.         {
  57.             $i++
  58.             $OU = Split-Path -Leaf $P      
  59.             $P = Split-Path -Parent $P
  60.             If ($i -ne 1)
  61.             {
  62.                 $ResOU = $ResOU + ","
  63.             }
  64.             $ResOU = $ResOU+ "OU=$OU"
  65.         }      
  66.     }  
  67.     else
  68.     {
  69.         $DNS_DOMAIN_NAME = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name      
  70.     }
  71.    
  72.     #Меняем точки на слэши, чтобы модно было использовать удобные функции для работы с путями
  73.     $DNS_DOMAIN_NAME = $DNS_DOMAIN_NAME.Replace(".","\")
  74.        
  75.  
  76.     $DC_NAMES = @()    
  77.     While ($DNS_DOMAIN_NAME -ne "")
  78.     {
  79.         $DC = Split-Path -Leaf $DNS_DOMAIN_NAME
  80.         $DNS_DOMAIN_NAME = Split-Path -parent $DNS_DOMAIN_NAME                 
  81.         $DC_NAMES = $DC_NAMES + $DC
  82.     }
  83.        
  84.        
  85.        
  86.     $Count = $DC_NAMES.Count   
  87.     for ($i=$Count;$i -gt 0;$i--)
  88.     {
  89.         $DC = $DC_NAMES[$i - 1]
  90.         If ($i -ne $Count)
  91.         {
  92.             $ResDC = $ResDC + ","
  93.         }
  94.         $ResDC = $ResDC+ "DC=$DC"      
  95.         if ($ResOU -ne $null)
  96.         {
  97.             $Res = $ResOU + "," + $ResDC       
  98.         }
  99.         else
  100.         {
  101.             $Res = $ResDC
  102.         }
  103.     }
  104.        
  105.     Return $Res
  106. }
  107.  
  108. <#
  109. .SYNOPSIS
  110.     Создает подразделение организации в AD с заданным именем по заданному пути.  
  111. .Description
  112.     При создании подразделения существование родителя не проверяется, что может вызвать проблемы.
  113.     Эта функция - служебная. Для создания подразделений рекомендуется использовать функцию
  114.     New-ADOrganizationUnit
  115.    
  116. .PARAMETER Path
  117.     Путь к подразделению AD, в котором будем создавать OU (т.е. родителю).
  118.    
  119. .PARAMETER Name
  120.     Имя создаваемого подразделения (Organization Unit).
  121.  
  122. .OUTPUTS   
  123.     $null. Функция не возвращает значений.
  124. #> 
  125. Function New-ADOrganizationUnit_simple([STRING]$Path,[STRING]$Name)
  126. {
  127.     #Отключаем сообщения об исключениях, т.к. они будут возникать довольно часто.
  128.     #основная причина - попытка создать OU, который уже существует.   
  129.     $ErrorActionPreference = "SilentlyContinue"
  130.    
  131.     #Конвертируем путь в нотацию DN (см. описание функции выше)
  132.     $OUDN = Convert-ADPath2DN -Path $Path  
  133.    
  134.     #Приводим путь к стандарту ADsPath
  135.     $OUDN = "LDAP://$OUDN" 
  136.    
  137.     #Создаем объект, представляющий текущий домен
  138.     $objDomain = [ADSI]$OUDN   
  139.    
  140.     #Создаем подразделение
  141.     $objOU = $objDomain.Create("organizationalUnit", "ou=$Name")
  142.     $objOU.SetInfo()
  143.    
  144.     #Обработка исключений
  145.     Trap
  146.     {
  147.         #Если дело в том, что такое подразделение уже есть, оповестим об этом пользователя. 
  148.         if ($_.Exception.ErrorCode -eq $SYSTEM_ERROR_CODE_OU_ALREADY_EXISTS)
  149.         {
  150.             Write-Host "OU $Name в $Path уже существует"
  151.         }
  152.     }
  153.    
  154. }
  155.  
  156. <#
  157. .SYNOPSIS
  158.     Создает подразделение организации в AD по заданному пути.
  159.    
  160. .Description
  161.     Будет создан не только последний элемент, но и вся родительская иерархия (все родительские подразделения).
  162.    
  163. .PARAMETER Path
  164.     Путь к создаваемому подразделению.
  165.  
  166. .OUTPUTS   
  167.     $null. Функция не возвращает значений.
  168. #> 
  169. Function New-ADOrganizationUnit ([STRING]$Path)
  170. {
  171.     #Проверяем, соответствует ли переданная строка пути к подразделению (example.com/Unit1/Unit2...)
  172.     If ($Path -match "^(?<DNS_DOMAIN_NAME>(\w+\.\w+)+)\/.+$")
  173.     {
  174.         $i = 0 
  175.         #Меняем направление слешей, чтобы использовать командлеты "*-Path"
  176.         $Pth = Join-Path $Path "/"
  177.         $Pth = $Pth.Replace("\","/")
  178.                
  179.         $OUs = @()
  180.         #Создаем OU по одному
  181.         While ($Pth -ne "")
  182.         {
  183.             $i++
  184.             $Pos = $Pth.IndexOf("/")           
  185.            
  186.             If ($i -eq 1)
  187.             {
  188.                 $DNS_DOMAIN_NAME = $Pth.Substring(0,$Pos)
  189.             }
  190.             else
  191.             {
  192.                 $OU = $Pth.Substring(0,$Pos)           
  193.                 $OUs = $OUs + $OU
  194.             }  
  195.             $Pth = $Pth.Substring($Pos+1,($Pth.Length - $Pos -1))          
  196.         }
  197.        
  198.         #Создаем весь путь OU
  199.         $Pth = $DNS_DOMAIN_NAME    
  200.         For ($i=0;$i -lt $OUs.Count;$i++)
  201.         {  
  202.             $OU = $OUs[$i]     
  203.             #Вызываем предыдущу функцию для непосредственного создания OU.
  204.             #Подразделения создаются "сверху вниз", поэтому ситуация создания
  205.             #дочернего подразделения при отсутствии родительского - исключена.
  206.             New-ADOrganizationUnit_simple -Name $OU -Path $Pth
  207.             $Pth = $Pth + "/" + $OU
  208.                
  209.         }      
  210.     }  
  211. }
  212.  
  213. <#
  214. .SYNOPSIS
  215.     Создает группу AD в заданном OU.  
  216.    
  217. .Description
  218.     Создает глобальную группу безопасности в заданном подразделении организации (Organization Unit).
  219.    
  220. .PARAMETER Path
  221.     Путь к подразделению организации, в котором нужно создать группу.
  222.    
  223. .PARAMETER Name
  224.     Имя создаваемой группы
  225.    
  226. .PARAMETER Force
  227.     Модификатор создания пути. Если он задан, то путь к OU будет принудительно создан.
  228.    
  229. .OUTPUTS   
  230.     $null. Данная функция не возвращает значений.
  231. #> 
  232. Function New-ADGroup([STRING]$Path, [STRING]$Name, [System.Management.Automation.SwitchParameter]$Force)
  233. {
  234.     #Если указано, принудительно создаём иерархию подразделений
  235.     $ErrorActionPreference = "SilentlyContinue"
  236.     If ($Force -eq $true)
  237.     {
  238.         New-ADOrganizationUnit -Path $Path     
  239.     }  
  240.     #Конвертируем понятное неспециалисту представление пути в DN
  241.     $OUDN = Convert-ADPath2DN -Path $Path
  242.    
  243.     #Создаем объект - представление домена
  244.     $OUDN = "LDAP://$OUDN"
  245.     $OU = [ADSI]"$OUDN"
  246.    
  247.     #Создаем и сохраняем группу безопасности в подразделении
  248.     $Group = $OU.Create("group", "cn=$Name")
  249.     $Group.Put("sAMAccountName", "$Name")
  250.     $Group.SetInfo()
  251.    
  252.     #Обработка исключений
  253.     Trap
  254.     {
  255.         #Наиболее часто возникающее исключение, не требующее остановки:
  256.         # "такая группа уже существует"
  257.         if ($_.Exception.ErrorCode -eq $SYSTEM_ERROR_CODE_OU_ALREADY_EXISTS)
  258.         {
  259.             Write-Host "Группа $Name в $Path уже существует"
  260.         }
  261.     }
  262. }
  263.  
  264. <#
  265. .SYNOPSIS
  266.     Позволяет определить GUID резервной копии GPO по её (копии) содержимому.  
  267.    
  268. .Description
  269.     Функция просматривает список дочерних папок в резервной копии GPO, находит среди них папку, имя которой - GUID, и
  270.     возвращает это значение в качестве GUID'а резервной копии. Идея метода в том, что корректная резервная копия GPO
  271.     содержит одну папку с именем в виде GUID'а. Этот имя этой папки - всегда соответствует GUID'у резервной копии.
  272.    
  273. .PARAMETER Path
  274.     Path - путь к папке, в которой находится резервная копия GPO.  
  275.  
  276. .OUTPUTS   
  277.     System.String. GUID резервной копии GPO, расположенной по заданному пути.
  278. #> 
  279. Function Get-ExportedBackupGUID([STRING]$Path)
  280. {
  281.     #Проверяем, доступна ли указанная папка, если нет - выбрасываем исключение
  282.     If (-not (Test-Path $Path))
  283.     {
  284.         Write-Host "Папки $Path не существует"
  285.         Throw "Backup dir path not found"      
  286.     }
  287.    
  288.     #Получаем список подпапок
  289.     $Children = Get-ChildItem -Force -LiteralPath $Path
  290.    
  291.     #Ищем в среди подпапок ту, которая именована GUID'ом
  292.     Foreach ($Child in $Children)
  293.     {  
  294.         If ($Child.FullName -match "^*\{\w{8}\-(\w{4}\-){3}\w{12}\}$")
  295.         {
  296.             Return $Matches[0]
  297.         }
  298.        
  299.     }  
  300.     #Папка доступна, но резервных копий GPO в ней нет.
  301.     Write-Host "В папке $Path не найдены резервные копии политик"
  302.     Throw "GPO Backup(s) not found"
  303. }
  304.  
  305. <#
  306. .SYNOPSIS
  307.     Создает новый объект групповой политики в заданном домене.
  308.    
  309. .Description
  310.     Привязка созданного объекта к подразделению организации не выполняется.  Для работы используется
  311.     COM-объект GPMC (соответственно, GPMC должна быть установлена).
  312.    
  313. .PARAMETER DomainDNSName
  314.     FQDN-имя домена, в котором будет создан объект групповой политики.
  315.  
  316. .PARAMETER GPOName
  317.     Имя создаваемого объекта групповой политики.
  318.  
  319. .OUTPUTS   
  320.     GPMGPO. Возвращает созданный объект групповой политики.
  321. #> 
  322. Function New-GPO([STRING]$DomainDNSName,[STRING]$GPOName)
  323. {  
  324.     $GPM = New-Object -ComObject GPMgmt.GPM
  325.     #Список предопределенных констант
  326.     $GPMConstants = $GPM.GetConstants()    
  327.     #Объект домена
  328.     $GPMDomain = $GPM.GetDomain($DNS_DOMAIN_NAME, $DNS_DOMAIN_NAME, $Constants.UseAnyDC)
  329.     #Создаем GPO
  330.     $GPMGPO = $GPMDomain.CreateGPO()
  331.     $GPMGPO.DisplayName = $GPOName
  332.    
  333.     Return $GPMGPO 
  334. }
  335.  
  336. <#
  337. .SYNOPSIS
  338.     Получает COM-объект заданной GPO по её имени.   
  339.    
  340. .Description
  341.     Позволяет получить пригодный для модификации объект GPO, зная её имя.   
  342.    
  343. .PARAMETER DomainDNSName
  344.     FQDN-имя домена, в котором выполняется поиск GPO.
  345.  
  346. .PARAMETER GPOName
  347.     Имя GPO, который нужно найти.
  348.    
  349. .OUTPUTS   
  350.     GPMGPO. Возвращает ссылку на COM-объект найденной GPO ( или $null, если GPO не была найдена).
  351. #> 
  352. Function Get-GPO([STRING]$DomainDNSName,[STRING]$GPOName)
  353. {
  354.     $GPMGPO = $null
  355.     #Отключаем реакции на возникающие исключения
  356.     $ErrorActionPreference = "SilentlyContinue"
  357.    
  358.     #Создаем объект, представляющий GPMC
  359.     $GPM = New-Object -ComObject GPMgmt.GPM
  360.    
  361.     #Список предопределенных констант
  362.     $GPMConstants = $GPM.GetConstants()    
  363.    
  364.     #Получаем объект GPMDomain, представляющий текущий домен
  365.     $GPMDomain = $GPM.GetDomain($DomainDNSNAme, $DomainDNSNAme, $GPMConstants.UseAnyDC)
  366.    
  367.     #Ищем групповую политику в домене по её имени
  368.     $GPMGPO = $GPMDomain.SearchGPOs($GPM.CreateSearchCriteria()) | Where-Object{$_.DisplayName -eq $GPOName}       
  369.    
  370.     #Возвращаем объект GPO. Если политика не найдена - вернется $null.
  371.     Return $GPMGPO
  372. }
  373.  
  374. <#
  375. .SYNOPSIS
  376.     Импортирует настройки GPO из резервной копии.  
  377.    
  378. .Description
  379.     Позволяет импортировать в заданный объект групповой политики настройки, сохраненные в виде резервной копии объетка GPO.
  380.     Речь идет именно об импрорте, а не восстановлении из резервной копии, поэтому допускается загрузка параметров из любого GPO.
  381.     Если целевого объекта GPO не существует, он будет создан.
  382.    
  383. .PARAMETER  BackupPath
  384.     Путь к папке с резервной копией GPO
  385.  
  386. .PARAMETER  DNS_DOMAIN_NAME
  387.     FQDN-имя домена, в котором находится целевая политика (реципиент).
  388.  
  389. .PARAMETER  MigrationTablePath
  390.     Не используется. Зарезервировано для будущих версий.
  391.  
  392. .PARAMETER  NewGPOName
  393.     Имя объекта групповой политики, в который нужно загрузить настройки из резервной копии. Если этот параметр не указан, имя будет взято из
  394.     резервной копии (т.е. параметры будут загружены в GPO с тем же именем, которое было у оригианльного GPO-донора).
  395.    
  396. .OUTPUTS   
  397.     $null. Функция не возвращает значений.
  398. #> 
  399. Function Import-GPO ([STRING]$BackupPath, [STRING]$DNS_DOMAIN_NAME, [STRING]$MigrationTablePath, [STRING]$NewGPOName = "")
  400. {  
  401.     #Проверяем доступность папки с резервной копией GPO. Если она недоступна, выбрасываем исключение
  402.     If (-not (Test-Path $BackupPath))
  403.     {
  404.         Write-Host "Неверно указана папка с архивом GPO: $BackupPath"
  405.         Throw "GPO Backup path not found"
  406.     }
  407.    
  408.     #Получаем COM-объект GPMC - представление домена
  409.     $GPM = New-Object -ComObject GPMgmt.GPM    
  410.     $GPMConstants = $GPM.GetConstants()        
  411.     $GPMDomain = $GPM.GetDomain($DNS_DOMAIN_NAME, $DNS_DOMAIN_NAME, $Constants.UseAnyDC)
  412.    
  413.     #Получаем объект GPMBackupDir, представляющий папку с резервной копией
  414.     $GPMBackupDir = $GPM.GetBackupDir($BackupPath) 
  415.     #Определяем GUID экспортированной GPO
  416.     $BackupGUID = Get-ExportedBackupGUID -Path $BackupPath
  417.     #Получаем объект - представление экспортированного GPO
  418.     $GPMBackup = $GPMBackupDir.GetBackup($BackupGUID)
  419.    
  420.     #Имя GPO, в которую будем импортировать настройки: если не указано, импортируем в объект с
  421.     #тем же именем, которое имеет резервная копия
  422.     If ($NewGPOName -eq "")
  423.     {
  424.         $TargetGPOName = $GPMBackup.GPODisplayName
  425.     }
  426.     else
  427.     {
  428.         $TargetGPOName = $NewGPOName
  429.     }
  430.        
  431.     #Находим в репозитории объект GPO, в который будем импортировать настройки
  432.     $GPMGPO = Get-GPO -DomainDNSNAme $DNS_DOMAIN_NAME -GPOName $TargetGPOName
  433.    
  434.     #Если GPO с заданным именем не нашелся, создаем его
  435.     If ($GPMGPO -eq $Null) 
  436.     {
  437.         $GPMGPO = New-GPO  -DomainDNSNAme $DNS_DOMAIN_NAME -GPOName $TargetGPOName
  438.     }
  439.    
  440.     #Импортируем содержимое GPO
  441.     $GPMGPO.Import(0, $GPMBackup) | Out-Null       
  442. }
  443.  
  444.  
  445. <#
  446. .SYNOPSIS
  447.     Выполняет присоединение (Link) объекта групповой политики к заданному подразделению организации (OU).
  448.    
  449. .Description
  450.     Присоединяет существующий объект GPO к существующему подразделению организации в рамках одного домена.
  451.     Кросс-доменное присоединение не поддерживается.
  452.    
  453. .PARAMETER  DomainDNSName
  454.     FQDN-имя домена, в котором выполняется операция присоединения.
  455.    
  456. .PARAMETER  GPOName
  457.     Имя присоединяемого объекта GPO. Объект должен быть доступен в репозитории объектов групповых политик заданного домена.
  458.    
  459. .PARAMETER  OUPath
  460.     Путь к подразделению организации, к которому нужно присоединить заданный объект GPO.
  461.  
  462. .OUTPUTS   
  463.     $Null. Данная функция не возвращает результат.
  464. #> 
  465. Function Mount-GPOToOU ([STRING]$GPOName,[STRING]$OUPath,[STRING]$DomainDNSName)
  466. {
  467.     #Ищем нужный объект GPO в репозитории домена
  468.     $GPMGPO = Get-GPO -DomainDNSName $DomainDNSName -GPOName $GPOName
  469.    
  470.     #Убеждаемся в том, что объект найден
  471.     If ($GPMGPO -ne $Null)
  472.     {  
  473.         #Приводим путь к нотации DN
  474.         $OUDN = Convert-ADPath2DN -Path $OUPath
  475.        
  476.         #Получаем представление домена в виде COM-объекта GPMC
  477.         $GPM = New-Object -ComObject GPMgmt.GPM    
  478.         $GPMConstants = $GPM.GetConstants()
  479.         $GPMDomain = $GPM.GetDomain($DomainDNSName, $DomainDNSName, $Constants.UseAnyDC)
  480.        
  481.         #Получаем представление интересующего подразделения
  482.         $GPMSOM = $GPMDomain.GetSOM($OUDN)     
  483.        
  484.         $ErrorActionReference = "SilentlyContinue"
  485.        
  486.         #Выполняем привязку (Link) объекта GPO к подразделению
  487.         $GPMSOM.CreateGPOLink(-1, $GPMGPO) | Out-Null
  488.        
  489.         $ErrorActionReference = "Continue"
  490.         trap
  491.         {
  492.             #Исключения создаются внутри COM-объекта. У нас нет возможности определять их причину.
  493.             #Как правило, она заключается в том, что указанный линк уже существует. Поэтому продолжаем
  494.             continue          
  495.         }
  496.        
  497.     }
  498.     #Если объект GPO по заданному имени не найден, сообщаем пользователю и выбрасываем исключение
  499.     else
  500.     {
  501.         Write-Host "Cannot find a GPO object named $GPOName"
  502.         Throw "Cannot_find_GPO"
  503.     }
  504. }
  505.  
  506.  
  507. <#
  508. .SYNOPSIS
  509.     Позволяет получить доменно-зависимый компонент SID
  510. .Description
  511.     SID многих стандартных участников безопасности включает в себя т.н. доменный компонент, отличающийся
  512.     у разных доменов. Данная функция позволяет получить его для текущего домена.   
  513. .OUTPUTS   
  514.     System.Security.Principal.SecurityIdentifier. SID текущего домена.
  515. #> 
  516. Function Get-DomainSID()
  517. {
  518.     $domain = [ADSI]""
  519.     $DomainSID = New-Object System.Security.Principal.SecurityIdentifier  ($Domain.objectSid.Value,0)
  520.     Return $DomainSID
  521. }
  522.  
  523. <#
  524. .SYNOPSIS
  525.     Пытается преобразовать заданную строку в Well-Known SID.   
  526.    
  527. .Description
  528.     Использует конструктор класса ystem.Security.Principal.WellKnownSidType для создания SID на основе заданной строки.
  529.     Написана для удобства перехвата исключений.
  530.    
  531. .PARAMETER  $Name
  532.     Строковое стандартного участника безопасности.
  533.    
  534. .OUTPUTS   
  535.     System.Security.Principal.WellKnownSidType или $null. Возвращает объект типа System.Security.Principal.WellKnownSidType,
  536.     соответствующий переданной строке или $null (если строке не соотвтествует ни один объект указанного типа).
  537. #> 
  538. Function Convert-ToSIDType([STRING]$Name)
  539. {
  540.     $Res = $null
  541.     $ErrorActionPreference = "SilentlyContinue"
  542.     $Res = [System.Security.Principal.WellKnownSidType]::$Name
  543.     $ErrorActionPreference = "Stop"
  544.     Return $Res
  545. }
  546.  
  547. <#
  548. .SYNOPSIS
  549.     Получает тип SID стандартных усатников безопасности.
  550.    
  551. .Description
  552.     Позволяет получить SID стандартных участников безопасности по имени / типу. Понимает константы
  553.     $SYSTEM_AD_STD_GROUP_NAME_*, а так же имена типов перечисления System.Security.Principal.WellKnownSidType
  554.    
  555. .PARAMETER  Name
  556.     Имя стандартного участника безопасности, SID которого нужно получить.
  557.    
  558. .OUTPUTS   
  559.     System.Security.Principal.WellKnownSidType. SID заданного участника безопасности
  560. #> 
  561. Function Get-WellKnownSIDFromName([STRING]$Name)
  562. {
  563.     #------Псевдонимы стандарных субъектов безопасности
  564.     $SYSTEM_AD_STD_GROUP_NAME_DOMAIN_ADMINS     =   "Domain Admins"  
  565.     $SYSTEM_AD_STD_GROUP_NAME_ENTERPRISE_ADMINS = "Enterprise Admins"  
  566.     $SYSTEM_AD_STD_GROUP_NAME_ENTERPRISE_DOMAIN_CONTROLLERS = "Enterprise Domain Controllers"  
  567.     $SYSTEM_AD_STD_GROUP_NAME_SYSTEM    =   "System"  
  568.     $SYSTEM_AD_STD_GROUP_NAME_AUTHENTICATED_USERS   =   "Authenticated Users"  
  569.     $SYSTEM_AD_STD_GROUP_NAME_DOMAIN_ADMIN  =   "Domain Administrator"  
  570.     $SYSTEM_AD_STD_GROUP_NAME_CREATOR_OWNERS    =   "Creator Owners"  
  571.     $DomainSID = Get-DomainSID
  572.     Switch ($Name)
  573.     {
  574.         $SYSTEM_AD_STD_GROUP_NAME_DOMAIN_ADMINS
  575.         {
  576.             #Администраторы домена (Группа)
  577.             #$SID = $DomainSID.value + "-512"  
  578.             $SIDType = [System.Security.Principal.WellKnownSidType]::AccountDomainAdminsSid
  579.         }
  580.        
  581.         $SYSTEM_AD_STD_GROUP_NAME_ENTERPRISE_ADMINS
  582.         {
  583.             #$SID = $DomainAdminsGroupSID = $DomainSID.value + "-519"  
  584.             $SIDType = [System.Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid
  585.         }
  586.        
  587.         $SYSTEM_AD_STD_GROUP_NAME_CREATOR_OWNERS
  588.         {
  589.             #$SID = $DomainAdminsGroupSID = $DomainSID.value + "-520"
  590.             $SIDType = [System.Security.Principal.WellKnownSidType]::CreatorOwnerSid
  591.         }
  592.        
  593.         $SYSTEM_AD_STD_GROUP_NAME_ENTERPRISE_DOMAIN_CONTROLLERS
  594.         {
  595.             #$SID = "S-1-5-9"          
  596.             $SIDType = [System.Security.Principal.WellKnownSidType]::EnterpriseControllersSid
  597.         }
  598.        
  599.         $SYSTEM_AD_STD_GROUP_NAME_SYSTEM
  600.         {
  601.             #$SID = "S-1-5-18"
  602.             $SIDType = [System.Security.Principal.WellKnownSidType]::LocalSystemSid
  603.         }
  604.        
  605.         $SYSTEM_AD_STD_GROUP_NAME_AUTHENTICATED_USERS
  606.         {
  607.             #$SID = "S-1-5-11"
  608.             $SIDType = [System.Security.Principal.WellKnownSidType]::AuthenticatedUserSid
  609.         }      
  610.        
  611.         default
  612.         {
  613.             #$SID = $null
  614.             $SIDType = $null
  615.             $SIDType = Convert-ToSIDType -Name $Name
  616.         }
  617.        
  618.     }  
  619.     Return $SIDType
  620.    
  621. }
  622.  
  623. <#
  624. .SYNOPSIS
  625.     Создает объект типа System.DirectoryServices.ActiveDirectoryRights по его имени.
  626.    
  627. .Description
  628.     Использует стандартный конструктор класса System.DirectoryServices.ActiveDirectoryRights.
  629.     Написана для удобства перехвата исключений.
  630.    
  631. .PARAMETER  StrRight
  632.     Строковое наименование элемента перечисления System.DirectoryServices.ActiveDirectoryRights.
  633.        
  634. .OUTPUTS   
  635.     System.DirectoryServices.ActiveDirectoryRights или $null. Возвращает объект типа System.DirectoryServices.ActiveDirectoryRights,
  636.     соотвтетствующий заданному имени, или $null (если такой объект не может быть создан)
  637. #> 
  638. Function Convert-ToAccessRight([STRING]$StrRight)
  639. {
  640.     $Res = $null
  641.     $ErrorActionPreference = "SilentlyContinue"
  642.     $Res = [System.DirectoryServices.ActiveDirectoryRights]::$StrRight
  643.     $ErrorActionPreference = "Stop"
  644.     Return $Res
  645. }
  646.  
  647. <#
  648. .SYNOPSIS
  649.     Создает объект - право доступа AD по его строковому имени.
  650.    
  651. .Description
  652.     Создает объект типа System.DirectoryServices.ActiveDirectoryRights. Принимает в качестве имени константы вида $SYSTEM_AD_GPO_PERMISSION_*
  653.     и строковые наименования типов перечисления System.DirectoryServices.ActiveDirectoryRights
  654.    
  655. .PARAMETER  RightSTR
  656.     Строковое имя создаваемого права доступа.
  657.  
  658. .OUTPUTS   
  659.     System.DirectoryServices.ActiveDirectoryRights или $null. Возвращает объект типа System.DirectoryServices.ActiveDirectoryRights, соответствующий
  660.     переданному строковому описанию, или $null (если такой объект не удалось найти).  
  661. #> 
  662. Function Get-GPOAccessRightFromString([STRING]$RightSTR)
  663. {
  664.  
  665.    
  666.     Switch ($RightSTR)
  667.     {
  668.         $SYSTEM_AD_GPO_PERMISSION_READ
  669.         {  
  670.             $Right = [System.DirectoryServices.ActiveDirectoryRights]::GenericRead
  671.         }
  672.        
  673.         $SYSTEM_AD_GPO_PERMISSION_WRITE
  674.         {
  675.             $Right = [System.DirectoryServices.ActiveDirectoryRights]::GenericWrite    
  676.         }
  677.        
  678.         $SYSTEM_AD_GPO_PERMISSION_CREATE_ALL_CHILD_OBJECT
  679.         {
  680.             $Right = [System.DirectoryServices.ActiveDirectoryRights]::CreateChild
  681.         }
  682.        
  683.         $SYSTEM_AD_GPO_PERMISSION_DELETE_ALL_CHILD_OBJECT
  684.         {
  685.             $Right = [System.DirectoryServices.ActiveDirectoryRights]::DeleteChild
  686.         }
  687.        
  688.         $SYSTEM_AD_GPO_PERMISSION_FULL_CONTROL
  689.         {
  690.             $Right = [System.DirectoryServices.ActiveDirectoryRights]::GenericAll
  691.         }
  692.        
  693.         default
  694.         {
  695.             $Right = $null         
  696.             $Right = Convert-ToAccessRight -StrRight $RightSTR
  697.         }      
  698.                
  699.     }
  700.    
  701.     Return $Right
  702. }
  703.  
  704. <#
  705. .SYNOPSIS
  706.     Формирует объект, представляющий собой право доступа к объектам AD.
  707.    
  708. .Description
  709.     Позволяет создать объект - правило доступа к объектам AD, зная тип доступа, строковое имя субъекта права и имя права.
  710.    
  711. .PARAMETER  Trustee
  712.     Строковое имя пользователя (или группы), который является субъектом права создаваемого правила.
  713.    
  714. .PARAMETER  Act
  715.     Тип доступа. Строковое наименования типов перечисления System.Security.AccessControl.AccessControlType (Allow или Deny)
  716.  
  717. .PARAMETER  Right
  718.     Строковое наименования права доступа. Допустимо использовать константы вида $SYSTEM_AD_GPO_PERMISSION_*
  719.     и строковые наименования типов перечисления System.DirectoryServices.ActiveDirectoryRights
  720.    
  721. .OUTPUTS   
  722.     System.DirectoryServices.ActiveDirectoryAccessRule или $null. Возвращает созданный объект правила доступа или $null (в случае, если
  723.     создать объект правила не удалось).   
  724. #> 
  725. Function New-ADGPOAccessRule ([STRING]$Trustee,[STRING]$Act,[STRING]$Right)
  726. {
  727.     $DomainSID = Get-DomainSID
  728.    
  729.     #-----------------
  730.     #Сначала разбираемся с субъектом прав.     
  731.     $objTrustee = $null
  732.     #Смотрим, не является ли наш субъект стандартным. Если да, то можно получить его SID, а уже по нему - имя.
  733.     #это обеспечит переносимость файлов конфигурации между разноязычными версиями ОС
  734.     $TruteeSID = Get-WellKnownSIDFromName -Name $Trustee   
  735.     If ($TruteeSID -ne $null)
  736.     {
  737.         $objTrustee = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $TruteeSID,$DomainSID
  738.     }
  739.     else #Субъект - не стандартный
  740.     {
  741.         [STRING]$FQDN = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
  742.         $objTrustee = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "$FQDN", "$Trustee"
  743.     }
  744.     If ($objTrustee -eq $null)
  745.     {
  746.         Write-Log -CurrentLogLevel 1 -Message "Не удалось найти участника безопасности, соответствующего имени $Trustee"
  747.         Throw "Err_no_security_principal_found_for_trustee"    
  748.     }
  749.    
  750.     #-----------------
  751.     #Теперь разбираемся с типом действия - разрешение это или запрет
  752.     $objACT = [System.Security.AccessControl.AccessControlType]::$Act
  753.    
  754.     #-----------------
  755.     #Формируем объект - задаваемое право
  756.     If ($Right -eq $SYSTEM_AD_GPO_PERMISSION_APPLY) #Речь идет о праве на применение GPO, оно формируется иначе, чем остальные
  757.     {
  758.         $NewRule = New-Object System.DirectoryServices.ExtendedRightAccessRule  -ArgumentList $objTrustee, $Act
  759.     }
  760.     else
  761.     {
  762.         $objRihgt = Get-GPOAccessRightFromString -Right $Right
  763.         if ($objRihgt -eq $null)
  764.         {
  765.             Write-Log -CurrentLogLevel 1 -Message "Не удалось определить право, соответствующее записи $Right"
  766.             Throw "Err_cannot_determine_ad_rights"     
  767.         }
  768.         $NewRule = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $objTrustee, $objRihgt, $objACT
  769.     }
  770.     Return $NewRule    
  771. }
  772.  
  773.  
  774. <#
  775. .SYNOPSIS
  776.     Сбрасывает разрешения (права доступа) для заданного объекта GPO и возвращает измененный объект.
  777.    
  778. .Description
  779.     Функция используется для сброса разрешений (прав доступа) на объект GPO к значениям по умолчанию.
  780.     Функция лишь возвращает объект и измененными правами доступа, не выполняя изменений в AD (она не делает Commit, его нужно
  781.     вызывать на измененном объекте явным образом).
  782.        
  783. .PARAMETER  GPO
  784.     Объект GPO, для которого нужно сбросить параметры доступа.
  785.  
  786. .PARAMETER ForceRemoveAllMode
  787.     Переключатель режима полного удаления всех заданных разрешений. Если он задан - то будут удалены все правила доступа к
  788.     объекту GPO. Если нет, то сначала будут удалены все правила доступа, а потом - заданы стандартные.
  789.  
  790. .OUTPUTS   
  791.     System.DirectoryServices.DirectoryEntry. Объект GPO, у которого сброшены права доступа.
  792. #> 
  793. Function Reset-ADGPOPermissions([System.DirectoryServices.DirectoryEntry]$GPO, [SYSTEM.Management.Automation.SwitchParameter]$ForceRemoveAllMode=$false)
  794. {
  795.     #Удаляем правила доступа. 
  796.     $AccessRules = $GPO.ObjectSecurity.Access
  797.     Foreach ($AccessRule in $AccessRules)
  798.     {
  799.         $GPO.ObjectSecurity.PurgeAccessRules($AccessRule.IdentityReference)
  800.     }
  801.    
  802.     # В большинстве случаев нам не нужно удалять вообще все правила. Как минимум,
  803.         # надо оставить доступ для Domain Controllers, Domain Admins и System
  804.        
  805.         if ($ForceRemoveAllMode -eq $false)
  806.         {
  807.             ##Задаем права для администраторов предприятия
  808.             #--Чтение
  809.             $NewRule = New-ADGPOAccessRule  -Trustee AccountEnterpriseAdminsSid -Act Allow -Right GenericRead          
  810.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null         
  811.             #--Запись        
  812.             $NewRule = New-ADGPOAccessRule  -Trustee AccountEnterpriseAdminsSid -Act Allow -Right GenericWrite         
  813.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null                     
  814.             #--Создание дочерних элементов
  815.             $NewRule = New-ADGPOAccessRule  -Trustee AccountEnterpriseAdminsSid -Act Allow -Right CreateChild          
  816.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null                     
  817.             #--Удаление дочерних элементов
  818.             $NewRule = New-ADGPOAccessRule  -Trustee AccountEnterpriseAdminsSid -Act Allow -Right DeleteChild          
  819.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null 
  820.            
  821.                        
  822.             ##Задаем права для контроллеров домена
  823.             #--Чтение
  824.             $NewRule = New-ADGPOAccessRule  -Trustee EnterpriseControllersSid -Act Allow -Right GenericRead            
  825.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null         
  826.            
  827.             ##Задаем права для локальной системы
  828.             #--Чтение
  829.             $NewRule = New-ADGPOAccessRule  -Trustee LocalSystemSid -Act Allow -Right GenericRead          
  830.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null         
  831.             #--Запись        
  832.             $NewRule = New-ADGPOAccessRule  -Trustee LocalSystemSid -Act Allow -Right GenericWrite         
  833.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null                     
  834.             #--Создание дочерних элементов
  835.             $NewRule = New-ADGPOAccessRule  -Trustee LocalSystemSid -Act Allow -Right CreateChild          
  836.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null                     
  837.             #--Удаление дочерних элементов
  838.             $NewRule = New-ADGPOAccessRule  -Trustee LocalSystemSid -Act Allow -Right DeleteChild          
  839.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null 
  840.            
  841.             <##Задаем права для прошедших проверку
  842.             #--Чтение
  843.             $NewRule = New-ADGPOAccessRule  -Trustee AuthenticatedUserSid -Act Allow -Right GenericRead            
  844.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null 
  845.             #--Применение
  846.             $NewRule = New-ADGPOAccessRule  -Trustee AuthenticatedUserSid -Act Allow -Right $SYSTEM_AD_GPO_PERMISSION_APPLY        
  847.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null 
  848.             #>
  849.            
  850.             ##Задаем права для себя, чтобы иметь возможность сохранить GPO-шку
  851.             $UserName = ([Security.Principal.WindowsIdentity]::GetCurrent()).Name
  852.             $objTrustee = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "$UserName"
  853.             #--Запись
  854.             $Right = [System.DirectoryServices.ActiveDirectoryRights]::GenericWrite
  855.             $Act = [System.Security.AccessControl.AccessControlType]::Allow
  856.             $NewRule = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $objTrustee, $Right, $Act
  857.             $GPO.ObjectSecurity.AddAccessRule($NewRule) | Out-Null
  858.            
  859.         }
  860.    
  861.     Return $GPO
  862. }
  863.  
  864. #===============</Модуль ActiveDirectory: функции>=================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement