Глава 16. Расширенное управление Active Directory с помощью PowerShell

В далёком 2006 я работал в большом Канадском поставщике службы управляемого хостинга. В то время имелся гигантский спрос на хостинг выделенных серверов. Оборудование, полоса пропускания и управление всё это стоило дорого. Однако вещи начали меняться с возникновением виртуализации: она смогла снизить стоимость хостинга. Я до сих пор помню о тех имевших место постоянных дискуссиях, спорах, статьях и встречах на высшем уровне, на которых люди обсуждали преимущества и недостатки виртуализации. Как и в случае с любой другой технологией, вначале существовали проблемы, однако технологии виртуализации развивались быстро и доводили бизнес до такой степени, что он не был способен оторвать взгляд.

Для нас это было точно так же: с точки зрения бизнеса мы находились в безопасности при выделенном хостинге. Мы получали хорошую прибыль. Однако при помощи виртуализации пользователи смогли перенести стойки выделенных серверов в несколько хостов гипервизора. Затем предприятия в области хостинга принялись искать новые способы заработка денег при помощи технологий виртуализации. Это было началом новой эры облачных технологий. Однако то что я хочу выделить, похоже на технологический переход от выделенных серверов к виртуализации: большинство современных инфраструктур переживают очень интересную фазу переноса рабочих нагрузок из локальной инфраструктуры в общедоступное облако. Когда был выпущен Microsoft Azur, мир технологий вновь наводнился всевозможными дискуссиями. Большинство моментов было связано с безопасностью данных, совместимостью, надёжностью и стоимостью.

На протяжении последних нескольких лет Microsoft решала все эти вызовы и проблемы и дошло до того, что организации не смогли оставаться в стороне от этого по следующим причинам:

  • Сама модель формирования цены облачного решения (плати только за используемые ресурсы) и модель работы могут сбить стоимость долговременных действий и сопровождения инфраструктуры.

  • Производители программного обеспечения начинают заменять свои продукты облачными версиями и прекращают поддержку локально применяемых версий.

  • Продукты Microsoft имеют эквивалентные локальным облачные версии, причём новые свойства будут доступны только в облачных версиях. Кроме того, такие облачные версии имеют более частые обновления и исправления ошибок по сравнению с локальными версиями.

  • Это удаляет зависимости (такие как подключение к сетевой среде, VPN и настройки межсетевого экрана) для мобильных работников и предоставляет из любого места бесшовный доступ к рабочим процессам.

  • Само облачное решение более быстро приспосабливает изменения новых технологий по сравнению с локальными инфраструктурами.

  • Надёжная настройка облачной инфраструктуры предоставляет высокую доступность (HA, high availability) для рабочих процессов, что может быть недостижимым локально.

Когда некая организация адаптируется к облачным технологиям, не так просто привнести за раз все и повсеместно рабочие процессы в общедоступное облако. Имеются ограничения для приложений, которые всё ещё требуют запуска каких- то рабочих процессов локально. Даже когда рабочие процессы работают в обеих технологиях, сама идентификация пользователей для организаций будет оставаться той же самой. AD (Active Directory) Azure помогает расширению имеющейся локальной инфраструктуры идентификации на аутентификацию в в приложениях и службах вне зависимости от того где они запускаются.

В данной главе мы рассмотрим такие темы:

  • Как интегрировать Azure AD с локальным AD

  • Синхронизацию хэшей паролей

  • Передача аутентификации Azure AD

  • Бесшовная SSO (Single Sign-On, Единая подпись) Azure AD.

  • Пошаговое руководство интеграции локальной среды AD с Azure AD.

Управление AD посредством PowerShell - подготовка

Модуль PowerShell содержит сборки, сценарии и функциональные возможности. Для применения имеющихся функциональных возможностей нам требуется импортировать этот модуль. После этого мы получаем способность вызова содержимого данного модуля для управления относящимися к делу ролями сервера, службами или свойствами. Прежде чем мы приступим к управлению AD при помощи PowerShell, для начала нам требуется импортировать соответствующий модуль ActiveDirectory.

Для осуществления этого имеется несколько способов. Они включают установку надлежащей роли сервера AD DS или производятся через RSAT (Remote Server Administration Tools, инструменты удалённого администрирования сервером):

  • Роль сервера AD DS:

    1. Когда мы устанавливаем роль своего сервера AD DS при помощи Диспетчера серверов, в качестве функциональных возможностей устанавливается Active Directory module for Windows PowerShell:

       

      Рисунок 16-1



    2. Когда роль AD DS устанавливается с применением PowerShell, нам требуется вложить инструментарий управления посредством использования IncludeManagementTools. В противном случае этот модуль не будет установлен:

      
      Install-WindowsFeature –Name AD-Domain-Services -IncludeManagementTools
      		
  • Remote Server Administration Tools:

    1. Даже когда определённый сервер не обладает установленной надлежащей ролью AD DS, среда имеющегося домена может управляться при помощи модуля PowerShell AD DS. Соответствующий модуль PowerShell AD содержится в RSAT и может быть установлен с применением Диспетчера сервера или PowerShell.

    2. В диспетчере сервера его можно отыскать переместившись в Features | Remote Server Administration Tools | Role Administration Tools | AD DS and AD LDS Tools | Active Directory module for PowerShell, как это показано на следующем снимке экрана:

       

      Рисунок 16-2



    3. Также его можно установить с применением PowerShell:

      
      Add-WindowsFeature RSAT-AD-PowerShell
      		
      [Замечание]Замечание

      Кроме того, существует также и возможность установки RSAT в ОС рабочего стола Windows. В качестве примера, можно выгрузить RSAT для Windows 10.

После установки необходимого модуля AD DS мы имеем возможность перечислить все доступные в этом модуле команды воспользовавшись такой командой:


Get-Command -Module ActiveDirectory
		

В данном модуле имеется примерно 147команд. Полный синтаксис для любой из команд можно просмотреть воспользовавшись следующей командой:


Get-Command commandname -Syntax
		

В качестве примера, приводимая ниже команда перечислит необходимый синтаксис для команды New-ADUser:


Get-Command New-ADUser -Syntax
		

Следующий снимок экрана отображает вывод для приведённой выше команды:

 

Рисунок 16-3



Для любой из команд команда Get-Help предоставляет подсказку. В качестве примера, приводимая далее команда предоставляет подсказку для команды New-ADUser:


Get-Help New-ADUser
		

Приводимый ниже снимок экрана отображает вывод приведённой выше команды:

 

Рисунок 16-4



Также мы имеем возможность просмотреть некий образец для своей команды New-ADUser при помощи следующего:


Get-Help New-ADUser -Example
		

отображаемый далее снимок экрана показывает вывод для нашей предыдущей команды:

 

Рисунок 16-5



Дополнительные сведения для конкретной команды можно просмотреть при помощи следующего:


Get-Help New-ADUser -Detailed
		

Технические сведения по определённой команде можно просмотреть воспользовавшись командой таким образом:


Get-Help New-ADUser -Full
		

Сведения о выбранной команде в реальном режиме времени можно просмотреть при помощи такого варианта:


Get-Help New-ADUser -Online
		

В этом разделе мы изучили как установить модуль Active Directory для PowerShell. Также мы изучили имеющиеся базовые функции этого модуля. теперь давайте пройдём дальше и изучим возможности управления Active Directory при помощи этого модуля.

Команды и сценарии управления AD

Данный модуль обладает 147 командами и их можно применять бесчисленными способами для управления конкретной средой AD. В данном разделе мы рассмотрим собственно возможности этих команд и поглядим как мы можем применять их для улучшения управления AD.

Я бы желал начать этот раздел с изучения того как мы можем просматривать имеющуюся конфигурацию некой среды AD. Самый быстрый способ просмотра конфигурации и возможностей конкретного сервера каталога состоит в применении такой команды:


Get-ADRootDSE
		

Эта команда предоставляет важные сведения, такие как уровни функциональности леса и домена, установленный по умолчанию контекст именования, значение текущего времени и тот контроллер домена, в котором выполнена текущая регистрация:

 

Рисунок 16-6



Наш следующий шаг состоит в поиске контроллеров домена в своём домене. Для перечисления значений имени контроллера домена, состояния его сервера глобального каталога и установленных ролей FSMO (Flexible Single Master Operation, Гибких операций единственного хозяина) мы можем применить следующее:


Get-ADDomainController -Filter * | Select-Object Name,IPv4Address,IsGlobalCatalog,OperationMasterRoles
		

Также важно иметь сведения относительно значения площадки AD, так как оно поясняет имеющуюся физическую топологию данного AD:


Get-ADDomainController -Filter * | Select-Object Name,IPv4Address,Site
		

Некий лес AD способен обладать множеством доменов. Наша следующая команла перечислит значения имён лесов, имён доменов, названий контроллеров доменов, IP адресов и площадки AD:


$Forestwide = (Get-ADForest).Domains | %{ Get-ADDomainController -Filter * -Server $_ }
write-output $Forestwide -Filter * | Select-Object Name,Forest,Domain,IPv4Address,Site
		

Когда нам известны значения имён доменов, мы способны перечислить соответствующие контроллеры домена и RODC (read-only domain controller), воспользовавшись такой командой:


$Domain = Read-Host 'What is your Domain Name ?'
Get-ADDomain -Identity $Domain | select ReplicaDirectoryServers,ReadOnlyReplicaDirectoryServer
		

При помощи этой команды его система запросит у своего пользователя ввод значения имени домена. После отклика пользователя она перечислит все контроллеры домена.

В нашей предыдущей команде, ReplicaDirectoryServers представит контроллеры домена с доступом на чтение и запись, а ReadOnlyReplicaDirectoryServer снабдит лишь контроллерами домена, доступными только для чтения.

Репликация

Для жизнеспособности некой среды AD критически важна репликация сведений. Для некого заданного контроллера домена мы можем найти его входящих партнёров реплик при помощи следующего:


Get-ADReplicationPartnerMetadata -Target REBEL-SRV01.rebeladmin.com
		

Наша предыдущая команда предоставляет подробное описание жизнеспособности определённой реплики заданного контроллера домена, включая самую последнюю реплику, раздел реплики, сервер и тому подобное.

Воспользовавшись своей следующей командой мы можем перечислить всех имеющихся входных партнёров для заданной репликации:


Get-ADReplicationPartnerMetadata -Target "rebeladmin.com" -Scope Domain
		

В нашей предыдущей команде её сфера действия определяется рамками домена. Это можно заменить на лес для получения списка всех входных партнёров в данном лесу. Получаемый вывод основывается на установленном по умолчанию разделе. Если это требуется, значение раздела может быть изменено с помощью –Partition для конфигурации или схемы раздела. Она перечислит всех относящихся к делу входных партнёров для данного выбранного раздела.

Соответствующие связанные отказы репликаций для площадки, домена и контроллера домена можно найти при помощи cmdlet Get-ADReplicationFailure:


Get-ADReplicationFailure -Target REBEL-SRV01.rebeladmin.com
		

Наша предыдущая команда перечислит все отказы репликаций для заданного контроллера домена.

Отказы репликаций для определённого домена могут быть найдены при помощи следующего:


Get-ADReplicationFailure -Target rebeladmin.com -Scope Domain
		

отказы репликаций для конкретного леса могут быть определены с применением такой команды:


Get-ADReplicationFailure -Target rebeladmin.com -Scope Forest
		

Отказы репликаций для заданной площадки можно отыскать воспользовавшись приводимой ниже команды:


Get-ADReplicationFailure -Target LondonSite -Scope Site
		

В приведённой выше команде LondonSite можно заменить необходимым вам названием площадки.

Воспользовавшись как Get-ADReplicationPartnerMetadata, так и Get-GetADReplicationFailure, я создал свой следующий сценарий PowerShell для выработки отчёта о жизнеспособности репликации для конкретного контроллера домена.

Самая первая часть данного сценария используется для задания того объекта, который мы будем применять на протяжении своего сценария:


## Active Directory Domain Controller Replication Status##
 $domaincontroller = Read-Host 'What is your Domain Controller?'
 ## Define Objects ##
 $report = New-Object PSObject -Property @{
 ReplicationPartners = $null
 LastReplication = $null
 FailureCount = $null
 FailureType = $null
 FirstFailure = $null
 }
 	   

В своём предыдущем сценарии я задал некий параметр для того чтобы конкретный инженер определил значение имени необходимого контроллера домена:


$domaincontroller = Read-Host 'What is your Domain Controller?'
		

В последующей части своего сценария я собираю приводимые ниже сведения, которые описывают значение сосотяния соединения репликации с иными контроллерами домена:

  • Партнёра по репликации (ReplicationPartners)

  • Последнюю успешную репликацию (LastReplication)


## Replication Partners ##
 $report.ReplicationPartners = (Get-ADReplicationPartnerMetadata -Target $domaincontroller).Partner
 $report.LastReplication = (Get-ADReplicationPartnerMetadata -Target $domaincontroller).LastReplicationSuccess
 	   

Далее я также собираю перечисленные ниже сведения, которые помогут инженерам в определении проблем с репликациями в случае их наличия:

  • Число отказов репликаций AD (FailureCount)

  • Тип отказа репликации AD (FailureType)

  • Первый раз регистрации отказа репликации AD (FirstFailure)


## Replication Faliures ~##
 $report.FailureCount = (Get-ADReplicationFailure -Target $domaincontroller).FailureCount
 $report.FailureType = (Get-ADReplicationFailure -Target $domaincontroller).FailureType
 $report.FirstFailure = (Get-ADReplicationFailure -Target $domaincontroller).FirstFailureTime
 	   

Самая последняя часть моего сценария форматирует получаемый вывод для всех собранных сведений:


## Format Output ##
 $report | select ReplicationPartners,LastReplication,FirstFailure,FailureCount,FailureType | Out-GridView
 	   

Последующий снимок экрана отображает получаемый вывод для нашего предыдущего сценария.

 

Рисунок 16-7



[Замечание]Замечание

Приводимый выше сценарий отображается неким упрощённым для понимания читателем способом. При его применении в PowerShell избегайте лишних пробелов.

Далее в топологиях репликаций AD имеются два типа репликаций:

  • Intra-site (внутри площадки): репликации между контроллерами домена в одной и той же площадке AD

  • Intra-site (между площадками):репликации между контроллерами домена из разных площадок AD

С помощью cmdlet Get-ADReplicationSite мы имеем возможность просмотра объектов реплицируемых площадок AD. Наша следующая команда вернёт все значения реплицируемых площадок определённого AD в заданном лесу AD:


Get-ADReplicationSite -Filter *
		

При помощи приводимой далее команды мы имеем возможность просмотра соединений реплицируемой площадки AD в определённом лесу AD:


Get-ADReplicationSiteLink -Filter *
		

В соединениях площадок наиболее важными сведениями выступают знания о стоимости данной площадки и установленном расписании репликаций. Это позволяет нам понимать имеющуюся топологию репликаций и ожидаемые задержки в репликациях.

приводимая далее команда перечисляет все имеющиеся связи реплицируемой площадки, которые содержат CanadaSite, совместно со значениями названия соединения, стоимостью соединения и частоты соединения:


Get-ADReplicationSiteLink -Filter {SitesIncluded -eq "CanadaSite"} | Format-Table Name,Cost,ReplicationFrequencyInMinutes -AutoSize
		

Для связывания воедино двух или более соединений площадок и включения прозрачности между соединениями площадок можно применять мосты соединений.

При помощи следующей команды можно выполнять выборку сведений о мосте соединений площадок:


Get-ADReplicationSiteLinkBridge -Filter *
		

Некоторые площадки AD применяют множество подсетей IP, которые назначаются площадкам для их работы. Для того чтобы контроллеры домена знали какие компьютеры располагаются в каких площадках важно ассоциировать эти подсети с площадками AD.

Приводимая далее команда выдаст список всех подсетей в данном лесу в виде некой таблицы со значениями названий подсети и площадки AD:


Get-ADReplicationSubnet -Filter * | Format-Table Name,Site -AutoSize
		

Серверы плацдарма работают в качестве соответствующей первичной точки взаимодействия для обработки поступающих и уходящих прочь из данной площадки AD реплицируемых сведений.

Мы имеем возможность перечислить все имеющиеся в неком домене серверы плацдарма:


$BHservers = ([adsi]"LDAP://CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration,DC=rebeladmin,DC=com").bridgeheadServerListBL
$BHservers | Out-GridView
		

В нашей предыдущей команде необходимое значение атрибута bridgeheadServerListBL получается через имеющееся соединение ADSI.

Сведения об имеющейся топологии репликаций оказывают инженерам содействие множеством способов, в частности при выявлении инженерами проблем с неисправностями репликаций Active Directory или при выполнении аудита некого Active Directory. При помощи своей предыдущей команды я создал свой следующий сценарий для получения сведений о топологии репликаций за один раз.

Как обычно, самая первая часть нашего сценария посвящается определению объектов:


## Script to gather information about Replication Topology ##
 ## Define Objects ##
 $replreport = New-Object PSObject -Property @{
 Domain = $null
 }
 	   

Прежде чем мы перейдём к самой репликации, неплохо собрать сведения о своём домене Active Directory. Это важно когда некая организация пользуется множеством доменов, ибо мы способны запросто разделять отчёты:


## Find Domain Information ##
 $replreport.Domain = (Get-ADDomain).DNSroot
 	   

Для перечисления имеющихся площадок Active Directory я воспользовался следующей частью своего сценария:


## List down the AD sites in the Domain ##
 $a = (Get-ADReplicationSite -Filter *)
 Write-Host "########" $replreport.Domain "Domain AD Sites" "########"
 $a | Format-Table Description,Name -AutoSize
 	   

Затем я намерен собрать сведения относительно имеющихся соединений реплицируемых площадок Active Directory и мосте соединений реплицируемых площадок Active Directory таким образом:


## List down Replication Site link Information ##
 $b = (Get-ADReplicationSiteLink -Filter *)
 Write-Host "########" $replreport.Domain "Domain AD Replication SiteLink Information" "########"
 $b | Format-Table Name,Cost,ReplicationFrequencyInMinutes -AutoSize
 ## List down SiteLink Bridge Information ##
 $c = (Get-ADReplicationSiteLinkBridge -Filter *)
 Write-Host "########" $replreport.Domain "Domain AD SiteLink Bridge Information" "########"
 $c | select Name,SiteLinksIncluded | Format-List
 	   

В вычислительных сетях существует множество подсетей IP. Эти подсети надлежит назначать должным образом площадкам Active Directory. Тем самым, компьютеры контроллеров домена Active Directory узнают к каким площадкам они относятся. Это также оказывает непосредственное воздействие на репликацию Active Directory. В своём следующем разделе мы намерены собрать сведения о подсети Active Directory и предпочтительных главных серверах мостов для данного домена:


## List down Subnet Information ##
 $d = (Get-ADReplicationSubnet -Filter * | select Name,Site)
 Write-Host "########" $replreport.Domain "Domain Subnet Information" "########"
 $d | Format-Table Name,Site -AutoSize
 ## List down Prefered BridgeHead Servers ##
 $e = ([adsi]"LDAP://CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration,DC=rebeladmin,DC=com").bridgeheadServerListBL
 Write-Host "########" $replreport.Domain "Domain Prefered BridgeHead Servers" "########"
 $e
 ## End of the Script ##
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

В своём предыдущем сценарии нам требуется заменить значение соединения ADSI относящимся к делу DN домена:


$e = ([adsi]"LDAP://CN=IP,CN=Inter-Site Transports,CN=Sites,CN=Configuration,DC=rebeladmin,DC=com")
		

Репликация конкретного объекта

После того как некий объект добавлен в какой- то контроллер домена, требуется реплицировать его во все прочие контроллеры домена. В противном случае пользователи столкнутся с проблемами в процессе регистрации с применением интегрированных с AD приложений и служб. Такая репликация зависит от множества различных факторов, таких как расписание репликации и соединения внутри площадки. Порой, однако, нам требуется принудительно выполнить соответствующую необходимую репликацию для понуждения реплицирования между контроллерами домена:


## Replicate Object to From Domain Controller to Another ##
$myobject = Read-Host 'What is your AD Object Includes ?'
$sourcedc = Read-Host 'What is the Source DC ?'
$destinationdc = Read-Host 'What is the Destination DC ?'
$passobject = (Get-ADObject -Filter {Name -Like $myobject})
Sync-ADObject -object $passobject -source $sourcedc -destination $destinationdc
Write-Host "Given Object Replicated to" $destinationdc
 	   

Наш предыдущий сценарий задаст несколько вопросов:

  • Name of object (название объекта): Не должно совпадать с DN (distinguished name). Всё что требуется, это чтобы текст содержался в поле имени этого объекта.

  • Source DC: Значение имени хоста DC источника.

  • Destination DC: Значение имени хоста DC получателя.

После предоставления надлежащих сведений указанный объект будет принудительно реплицирован:

 

Рисунок 16-8



В этом разделе данной главы мы изучили как можно применять имеющийся модуль PowerShel Active Directory для просмотра установленной топологии некой среды Active Directory. Также мы изучили как мы можем осуществлять аудит, поиск неисправностей и управление репликациями с применением PowerShell. В своём следующем разделе мы обираемся взглянуть на управление объектом Active Directory.

Пользователи и группы

В этом разделе давайте взглянем на команды и сценарии PowerShell, которые мы можем применять для управления пользователями и группами AD.

Время последней регистрации

при определённых обстоятельствах нам необходимо отыскивать когда какой- то пользователь выполнял успешную регистрацию в домене. Это может служить целям аудита или поиска неисправностей:


$username = Read-Host 'What is the User account you looking for ?'
   $dcs = Get-ADDomainController -Filter {Name -like "*"}
      foreach($dc in $dcs)
   { 
     $hostname = $dc.HostName
     $user = Get-ADUser $userName -Server $hostname -Properties lastLogon
     $lngexpires = $user.lastLogon
     if (-not ($lngexpires)) {$lngexpires = 0 }
     If (($lngexpires -eq 0) -or ($lngexpires -gt [DateTime]::MaxValue.Ticks))
     {
       $LastLogon = "User Never Logged In"
     }
      Else
     {
       $Date = [DateTime]$lngexpires
       $LastLogon = $Date.AddYears(1600).ToLocalTime()
     }
  }
  Write-Host $username "last logged on at:" $LastLogon
 	   

Наш предыдущий сценарий запросит имя пользователя определённой учётной записи и, после его предоставления, наша система отыщет необходимое значение атрибута lastLogon во всех доступных контроллерах домена. Если его нельзя найти, он возвратит User Never Logged In , или, в случае обнаружения, он вернёт значение временной метки последней регистрации.

Отчёт о дате последней регистрации

Для целостности требуется периодическая чистка в AD. Могут существовать объекты пользователей, которые не использовались на протяжении лет. Если бы мы могли создать некий общий отчёт с самыми последними датами входа в систему, мы бы могли применять их в качестве справочника для очистки объектов:


## Script For Filter user with Last logon Time ##
$htmlformat = "<style>BODY{background-color:LightBlue;}</style>"
Get-ADUser -Filter * -Properties "LastLogonDate" | sort-object -property lastlogondate -descending | Select-Object Name,LastLogonDate | ConvertTo-HTML -head $htmlformat -body "<H2>AD Accounts Last Login Date</H2>"| Out-File C:\lastlogon.html
Invoke-Expression C:\lastlogon.html
 	   

Этот сценарий создаёт некий отчёт HTML, который содержит все учётные записи пользователей с их временными отметками самой последней даты входа в систему:

 

Рисунок 16-9



Отчёт о об отказах регистрации

Важно знать о попытках с отказами в регистрации в рассматриваемом DC, а не только об успешных попытках. Они могут являться результатами потенциальных вредоносных действий.

Приводимый ниже сценарий создаст некий отчёт для указания отказов во входе в систему в неком заданном контроллере домена:


## Report for DC login Failures ##
$failedevent = $null
$Date= Get-date 
$dc = Read-Host 'What is the Domain Controller ?'
$Report= "C:\auditreport.html"
$HTML=@"
<title>Failed Login Report for $dc</title>
<style>
BODY{background-color :LightBlue}
</style>
"@
 $failedevent = Get-Eventlog security -Computer $dc -InstanceId 4625 -After (Get-Date).AddDays(-7) |
 Select TimeGenerated,ReplacementStrings |
 % {
 New-Object PSObject -Property @{
 SourceComputer = $_.ReplacementStrings[13]
 UserName = $_.ReplacementStrings[5]
 SourceIPAddress = $_.ReplacementStrings[19]
 Date = $_.TimeGenerated
 }
 }
 $failedevent | ConvertTo-Html -Property SourceComputer,UserName,SourceIPAddress,Date -head $HTML -body "<H2>Failed Login Report for $dc</H2>"|
 Out-File $Report
 Invoke-Expression C:\auditreport.html
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

Когда вы запустите наш предыдущий сценарий, он запросит название того контроллера домена, для которого вы желаете выполнить данный отчёт. Затем, в фоновом режиме, он отыщет событие 4625 в имеющемся просмотрщике событий. а затем выводится отчёт списка следующих сведений:

  • Значение компьютера источника

  • Значение имени пользователя

  • Значение адреса IP источника

  • Время данного события

Приводимый далее снимок экрана показывает отчёт отказов для REBEL-PDC-01:

 

Рисунок 16-10



Поиск блокированной учётной записи

При назначенных политиках пароля, учётные записи с большим числом отказов во входе в систему будут заблокированы. Заблокированные учётные записи в некой среде AD можно отыскать при помощи такой команды:


Search-ADAccount -Lockedout | Select name,samAccountName,Lockedout
		

Когда кто- то из этого списка должен быть разблокирован, мы можем воспользоваться для разблокирования учётной записи имеющимся cmdlet Unlock-ADAccount.

Для некой индивидуальной учётной записи выполните следующую команду:


Unlock-ADAccount tuser4
		

Для всех учётных записей из полученного списка выполните такую команду:


Search-ADAccount -Lockedout | Unlock-ADAccount
		

Отчёт об истечении срока действия пароля

Распространённым обращением в службу поддержки являются проблемы, вызванные истечением срока паролей. Приводимый ниже сценарий способен выработать некий отчёт относительно паролей с истекшей датой:


## Password Expire Report ##
$passwordreport = $null
$dc = (Get-ADDomain | Select DNSRoot).DNSRoot
$Report= "C:\passwordreport.html"
$HTML=@"
<title>Password Expire Report For $dc</title>
<style>
BODY{background-color :LightBlue}
</style>
"@
$passwordreport = Get-ADUser -filter * –Properties "SamAccountName","pwdLastSet","msDS-UserPasswordExpiryTimeComputed" | Select-Object -Property "SamAccountName",@{Name="Last Password Change";Expression={[datetime]::FromFileTime($_."pwdLastSet")}},@{Name="Next Password Change";Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}
$passwordreport | ConvertTo-Html -Property "SamAccountName","Last Password Change","Next Password Change"-head $HTML -body "<H2>Password Expire Report For $dc</H2>"|
Out-File $Report
Invoke-Expression C:\passwordreport.html
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

Данный сценарий отыщет необходимые значения атрибутов для SamAccountName, pwdLastSet и msDS-UserPasswordExpiryTimeComputed во всех объектах пользователей. Далее они будут представлены в отчёте HTML:

 

Рисунок 16-11



[Совет]Совет

Все эти отчёты могут запускаться в качестве заданий расписания и могут быть доработаны до отправки в виде электронного письма еженедельно или раз в месяц. Это сбережёт время администратора, а также предохранит от ошибок, которые могут происходить при выполнении задач вручную.

JEA

В своей предыдущей главе я дал пояснения относительно того как работает в некой инфраструктуре JEA для целей безопасности связанных с учётными записями домена полномочий. Если вкратце, мы можем создавать конечные точки JEA и назначать их ролям. Пользователям нет нужды в обладании такими полномочиями как администратор домена или предприятия для исполнения этого. Пользователи могут применять такие конечные точки при помощи своих обычных учётных записей пользователя AD. Тем не менее, в такой окончательной JEA, команды выполняются с использованием JEA учётной записи локального администратора. Эти подробности входа в систему не должны быть известны конечным пользователям, а их пароли автоматически сбрасываются на ежедневной основе.

Как и было обещано в нашей предыдущей главе, давайте теперь рассмотрим как получить установленными и настроенными JEA.

Для установки JEA прежде всего войдите в соответствующий сервер в качестве пользователя, который обладает полномочиями локального администратора и откройте PowerShell:


Install-Module xJEA
		

После его установки мы способны убедиться в этом при помощи такой команды:


Find-Module –Name xJEA | fl
		

Настройка JEA

Теперь, когда мы обладаем установленным модулем JEA, наш следующий шаг состоит в подготовке необходимой среды для применения JEA. Это можно осуществить при помощи сценария, который поступает с самим модулем JEA. Он располагается в C:\Program Files\WindowsPowerShell\Modules\xJea\0.2.16.6\Examples\SetupJEA.ps1.

Этот сценарий осуществит следующее:

  • Удалит все имеющиеся конечные точки с данного компьютера

  • Настроит имеющегося DSC LCM (Local Configuration Manager, Диспетчера локальных настроек) принять изменения и далее выполнять проверку каждые 30 минут чтобы убеждаться в том, что нет изменений данной настройки

  • Включить необходимый режим отладки


Configuration SetupJea
    {
      Import-DscResource -module xjea Node localhost
      {
        xJeaEndPoint CleanAll
        {
          Name     = 'CleanALL'
          CleanAll = $true
        }
        LocalConfigurationManager
        {
          RefreshFrequencyMins = 30
          ConfigurationMode    = "ApplyAndAutoCorrect"
          DebugMode            = "ForceModuleImport"  
          #This disables provider caching
        }
      }
    }
    SetupJea -OutputPath C:\JeaDemo
    Set-DscLocalConfigurationManager -Path C:\JeaDemo -Verbose
    Start-DscConfiguration -Path c:\JeaDemo -Wait -Verbose
    #EOF
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

Для запуска этого сценария перейдите в каталог C:\Program Files\WindowsPowerShell\Modules\xJea\0.2.16.6\Examples\ и запустите .\SetupJEA.ps1, как это показано на следующем снимке экрана:

 

Рисунок 16-12



Теперь мы завершили необходимую установку и первоначальную настройку.

Проверка

JEA поставляется с тремя демонстрационными настройками конечных точек, которыми можно пользоваться в качестве руководства для создания некой конечной точки. Эти демонстрационные файлы расположены в C:\ProgramFiles\WindowsPowerShell\Modules\xJea\0.2.16.6\Examples, а также Demo1.ps1, который содержит следующее:


cls configuration Demo1
{
  Import-DscResource -module xjea
  xJeaToolKit Process
  {
    Name         = 'Process'
    CommandSpecs = @"Name,Parameter,ValidateSet,ValidatePattern Get-Process 
    Get-Service Stop-Process,Name,calc;notepad 
    Restart-Service,Name,,^A"@
  }
  xJeaEndPoint Demo1EP
  {
    Name                   = 'Demo1EP'
    Toolkit                = 'Process'
    SecurityDescriptorSddl = 
      'O:NSG:BAD:P(A;;GX;;;WD)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)'                     
    DependsOn              = '[xJeaToolKit]Process'
  }
}
Demo1 -OutputPath C:\JeaDemo

Start-DscConfiguration -Path C:\JeaDemo -ComputerName localhost -Verbose -wait -debug -ErrorAction SilentlyContinue -ErrorVariable errors
if($errors | ? FullyQualifiedErrorId -ne 'HRESULT 0x803381fa')
{
    $errors | Write-Error    
}

start-sleep -Seconds 30 #Wait for WINRM to restart

$s = New-PSSession -cn . -ConfigurationName Demo1EP
Invoke-command $s {get-command} |out-string
Invoke-Command $s {get-command stop-process -Syntax}
# Enter-pssession $s
Remove-PSSession $s
#EOF
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

Что касается настроек такой конечной точки, пользователям разрешается применять лишь такие cmdlet:

  • Get-Process

  • Get-Service

  • Stop-Process,Name,calc;notepad

  • Restart-Service,Name,^A

Наш предыдущий cmdlet Stop-Process может применяться только для останова калькулятора. Однако он также позволяет вам применять без ограничений Restart-Service, Get-Process и Get-Service.

Для развёртывания этой конечной точки мы можем применить .\Demo1.ps1.

После успешного выполнения этого мы можем проверить настройку полученного нового сеанса PowerShell при помощи следующего:


Get-PSSessionConfiguration
		

Следующий снимок экрана отображает вывод нашей предыдущей команды:

 

Рисунок 16-13



Наш следующий этап состоит в подключении к новой конечной точке. Это можно сделать при помощи такой команды:


Enter-PSSession –ComputerName localhost –ConfigurationName demo1ep
		

В нашей предыдущей команде –ConfigurationName задаёт значение названия конечной точки.

Как только мы выполним эту команду, наша система подключается к соответствующей конечной точке и изменяет значение пути на C:\Users\JSA-Demo1EP\Documents:

 

Рисунок 16-14



Этот пользователь устанавливается в качестве части общего процесса установки со стороны JEA. Он выступает в качестве учётной записи данного сеанса PowerShell. Также эта учётная запись является частью группы локальных администраторов:

 

Рисунок 16-15



Наш следующий снимок экрана подтверждает такое участие в локальной группе безопасности Administrators:

 

Рисунок 16-16



После осуществления подключения данного сеанса мы можем проверить его вначале при помощи разрешённой команды. В соответствии с имеющимися настройками, нам теперь дозволено запускать команду Get-Service без каких бы то ни было ограничений:

 

Рисунок 16-17



Тот пользователь, под которым я вошёл в данный компьютер является локальным администратором. Поэтому я обладаю достаточными полномочиями для перезапуска этого компьютера при помощи cmdlet Restart-Computer. Однако когда я применяю эту команду через созданную конечную точку, это должно мне быть запрещено в соответствии с настройкой этой конечной точки.

 

Рисунок 16-18



Как мы можем видеть из предыдущего снимка экрана, всё работает как мы и ожидали. Пользователям дозволено работать исключительно с командами, допускаемыми конфигурацией этой конечной точки. Эти настройки не будут допустимыми для иного компьютера пока не применяются те же самые настройки конечной точки.

Настройки конечной точки Demo2.ps1 сосредоточены вокруг соответствующего администратора файлового сервера:


cls
configuration Demo2
{
  Import-DscResource -module xjea

  xJeaToolKit SMBGet
  {
    Name = 'SMBGet'
    CommandSpecs = @" Module,Name,Parameter,ValidateSet,ValidatePattern
      SMBShare,get-* "@
  }
  xJeaEndPoint Demo2EP
  {
    Name = 'Demo2EP'
    Toolkit = 'SMBGet'
    SecurityDescriptorSddl = 'O:NSG:BAD:P(A;;GX;;;WD)S:P(AU;FA;GA;;;WD)
      (AU;SA;GXGW;;;WD)' 
    DependsOn = '[xJeaToolKit]SMBGet'
  }
}

Demo2 -OutputPath C:\JeaDemo
Start-DscConfiguration -Path C:\JeaDemo -ComputerName localhost -Verbose ` -wait -debug -ErrorAction SilentlyContinue -ErrorVariable errors
if($errors | ? FullyQualifiedErrorId -ne 'HRESULT 0x803381fa')
{
 $errors | Write-Error 
}

start-sleep -Seconds 30 #Wait for WINRM to restart

$s = New-PSSession -cn . -ConfigurationName Demo2EP
Invoke-command $s {get-command} |out-string
# Enter-pssession $s

Remove-PSSession $s
#EOF
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

В соответствии с нашим предыдущим сценарием, данная система позволит вам применять без ограничений следующий список cmdlet:

  • SMBShare

  • get-*

Наш следующий снимок экрана отображает вывод для команды Get-PSSessionConfiguration.

Мы можем подключиться ко своей второй конечной точке при помощи такой команды:


Enter-PSSession –ComputerName localhost –ConfigurationName demo2ep
		

После подключения Get-Command перечислит все доступные в этой конечной точке команды:

 

Рисунок 16-19



Как и ожидалось, она допускает для нас запуск исключительно разрешённых cmdlet. В данной проверке мы воспользуемся cmdlet Get-SMBshare, который разрешён и Restart-Computer, который запрещён:

 

Рисунок 16-20



Demo3.ps1 предоставляет свою конечную точку для управления файловой системой и навигации по ней:


cls configuration Demo3
{
  Import-DscResource -module xjea
  xJeaToolKit FileSystem
  {
    Name = 'FileSystem'
    CommandSpecs = @" Module,name,Parameter,ValidateSet,ValidatePattern,
      Get-ChildItem,Get-Item,Copy-Item,Move-Item,Rename-Item,
      Remove-Item,Copy-ItemProperty,Clear-ItemProperty,Move-ItemProperty,
      New-ItemProperty,Remove-ItemProperty,Rename-ItemProperty,Set-ItemProperty,
      Get-Location,Pop-Location,Push-Location,Set-Location,Convert-Path,
      Join-Path,Resolve-Path,Split-Path,Test-Path,Get-PSDrive,New-PSDrive,
      out-file "@
    Ensure = 'Present' 
  }
 
  xJeaEndPoint Demo3EP
  {
     Name = 'Demo3EP'
     ToolKit = 'FileSystem'
     Ensure = 'Present'
     DependsOn = '[xJeaToolKit]FileSystem'
  }
}

Demo3 -OutputPath C:\JeaDemo

Start-DscConfiguration -Path C:JeaDemo -ComputerName localhost -Verbose ` -wait -debug -ErrorAction SilentlyContinue -ErrorVariable errors
if($errors | ? FullyQualifiedErrorId -ne 'HRESULT 0x803381fa')
{
 $errors | Write-Error 
}

start-sleep -Seconds 30 #Wait for WINRM to restart
# This endpoint allows you to navigate the filesystem but not see 
# the CONTENTS of any of the files
$s = New-PSSession -cn . -ConfigurationName Demo3EP
Invoke-command $s {dir 'C:\Program Files\Jea\Activity\ActivityLog.csv'} 
Invoke-Command $s {get-content ` 'C:Program FilesJeaActivityActivityLog.csv'}
# Enter-pssession $s

Remove-PSSession $s
#EOF
 	   
[Замечание]Замечание

Наш приведённый выше сценарий отображается неким простым способом для понимания читателями. При его применении в PowerShell избегайте лишних пробельных строк.

Настройки его конечной точки позволяют нам применять такие cmdlet:

  • Get-ChildItem

  • Get-Item

  • Copy-Item

  • Move-Item

  • Rename-Item

  • Remove-Item

  • Copy-ItemProperty

  • Clear-ItemProperty

  • Move-ItemProperty

  • New-ItemProperty

  • Rename-ItemProperty

  • Set-ItemProperty

  • Get-Location

  • Pop-Location

  • Push-Location

  • Set-Location

  • Convert-Path

  • Join-Path

  • Resolve-Path

  • Split-Path

  • Test-Path

  • Get-PSDrive

  • New-PSDrive

  • out-file

Это объясняет как мы можем применять конечные точки JEA для ограничения полномочий конкретного использования на определённые задачи. Данный сценарий может использоваться для сборки вашей собственной конфигурации. Имеется множество примеров, которые вы можете отыскать в GitHub. Вы можете выполнить доступ к странице GitHub JEA через https:/​/​github.​com/​PowerShell/​JEA.

До сих пор в этой главе мы изучали то как мы можем применять модуль Powershell Active Directory для управления неким окружением Active Directory. Однако когда дело доходит до некой гибридной среды, мы не можем воспользоваться тем же самым модулем и для управления AD Azure. Для управления объектами Azure AD (исключительно облачными и синхронизированными) нам придётся применять модуль PowerShell Azure Active Directory. В своём следующем разделе этой главы мы намерены исследовать модуль PowerShell Azure Active Directory и его возможности.

Azure AD PowerShell

Аналогично локальному Active Directory, мы можем также применять PowerShell и в Azure Active Directory. Давайте рассмотрим зачем нам следует применять PowerShell для управления Azure Active Directory:

  • Доступ к только что появившимся возможностям: Microsoft продолжает выпуск новых свойств, исправлений, обновлений и расширенных возможностей более часто в службах Azure AD, нежели в локальных Active Directory.

    Microsoft осуществляет выпуск новых возможностей для общего доступа в два этапа. На первой стадии они выпускаются в качестве версии для предварительного знакомства. Их не рекомендуется применять в промышленном применении, однако профессионалы могут использовать их для тестирования и выполнять обратную связь с Microsoft. На этом этапе данная функциональность может обладать множеством обновлений и, в большинстве случаев, для надлежащего обновления в GUI потребуется какое- то время. Некоторые из таких изменений не будут доступны в GUI до основного выпуска. Тем не менее, когда мы пользуемся PowerShell, нам не приходится ждать. Мы можем получать ранний доступ к свойствам сразу после их выпуска.

  • Более быстрый отклик: Портал Azure Active Directory обладает большим числом различных окон, мастеров, форм настроек и управления пользователями, группами, ролями и связанными с этим свойствами. Этот GUI упрощает эти моменты, но требует времени. Например, когда вы добавляете учётную запись некого пользователя при помощи портала Azure AD, вам приходится по крайней мере проходить четыре подчинённых окна. В то время как PowerShell позволяет нам сделать это в одном окне и несколькими строками команд.

  • Гранулированное управление: Портал Azure AD визуализирует сами данные и настройки служб применяя различные окна. Тем не менее, это может не всегда тем что вам требуется. Например, давайте допустим что мы ищем конкретное значение в двух учётных записях пользователей. Когда мы применяем имеющийся GUI, для получения этих сведений нам требуется пройти через несколько различных окон. Однако, воспользовавшись командой или сценарием PowerShell мы будем способны получить те же самые сведения в одном окне. При устранении неисправностей это на самом деле полезно.

  • Интеграция с Microsoft Graph: Microsoft Graph предоставляет единообразную программируемую модель для доступа к гигантским объёмам сведений в Microsoft 365, Azure Active Directory, Enterprise Mobility Suite, Windows 10 и так далее. Будучи его частью, имеющийся модуль Azure AD PowerShell for Graph позволяет вам выполнять выборку сведений, обновлять настройки каталога, добавлять/ обновлять/ удалять объекты и настраивать свойства через Microsoft Graph.

В этой главе для управления Azure AD я буду применять Azure Active Directory PowerShell for Graph.

Установка

Необходимый нам модуль Azure Active Directory PowerShell for Graph поставляется в двух версиях. Имеющаяся в общем доступе версия предварительного просмотра является наиболее распространённой, но не рекомендуется для промышленного применения. Основные шаги для установки данной версии можно отыскать в https://www.powershellgallery.com/packages/AzureADPreview.

Общедоступная версия является стабильной, рекомендуемой для промышленных сред. Её можно установить на любой компьютер, запущенный под Windows Server 2008 R2 или выше с самыми последними обновлениями. Также необходим Microsoft .NET Framework 4.5 или выше.

После выполнения всех предварительных требований, осуществите такие шаги:

  1. Зарегистрируйтесь в своём компьютере, который вы выбрали для устанавливаемого модуля Azure Active Directory PowerShell for Graph.

  2. Запустите консоль PowerShell от имени администратора.

  3. Запустите команду Install-Module -Name AzureAD. Если она запросит обновления необходимого репозитория, ответьте Yes:

     

    Рисунок 16-21



  4. После установке мы можем убедиться с том что этот модуль установлен воспользовавшись Get-Module AzureAD.

  5. Для инициализации подключения к своей аренде Azure AD, после успешной установки необходимого модуля выполните Connect-AzureAD.

  6. Далее он пригласит вас в окне входа в систему. Для подключения воспользуйтесь подробностями учётной записи глобального администратора Azure AD.

Теперь у нас имеется установленный модуль Azure Active Directory PowerShell for Graph. Давайте рассмотрим как мы можем при помощи этого модуля управлять гибридной средой Azure AD.

Общие команды

Мы можем начать с перечисления всех доступных в нашем модуле Azure AD команд, что можно сделать таким образом:


Get-Command -module AzureAD
		

При помощи команды Get-Help мы можем просматривать полный синтаксис команд. Например, пр помощи следующей команды мы способны увидеть полный синтаксис для команды Get-AzureADUser:


Get-Help Get-AzureADUser
		

Воспользовавшись своей следующей командой мы способны проверить состояние доменов Azure AD:


Get-AzureADDomain | fl
		

Наша предыдущая команда помогает идентифицировать состояние проверки нашего домена по ссылке на значение атрибута IsVerified.

Когда вы применяете в Azure AD некий индивидуально настроенный домен, нам требуется проверить владельца этого домена с применением записей DNS. Если эта проверка не прошла, мы можем выполнить выборку необходимых записей DNS, воспользовавшись такой командой:


Get-AzureADDomainVerificationDnsRecord -Name M365x562652.onmicrosoft.com | fl
		

В нашем предыдущем примере, M365x562652.onmicrosoft.com представляет имя нашего домена:

 

Рисунок 16-22



Мы можем просмотреть подробности аренды Azure AD применив следующее:


Get-AzureADTenantDetail | fl
		

В некой гибридной среде критически важной является жизнеспособность синхронизации локального AD. Мы можем просмотреть значение времени самой последней синхронизации каталога, воспользовавшись такой командой:


Get-AzureADTenantDetail | select CompanyLastDirSyncTime
		

Управление пользователями

Мы имеем возможность просмотра необходимых подробностей учётной записи пользователя для некой известной учётной записи применяя следующее:


Get-AzureADUser -ObjectId AdeleV@M365x562652.OnMicrosoft.com | fl
		

А нашей предыдущей команде AdeleV@M365x562652.OnMicrosoft.com представляет собой значение UPN для указанного пользователя.

Мы также способны применять атрибуты пользователя для поиска подробностей учётной записи пользователя:


Get-AzureADUser -Filter "startswith(GivenName,'Adele')"
		

Наша предыдущая команда отфильтрует пользователей Azure AD по GivenName при помощи Adele.

Мы также можем фильтровать пользователей на основании значения некого особого атрибута:


Get-AzureADUser -Filter "GivenName eq 'Adele'"
		

Эта предыдущая команда найдёт всех пользователей в точности имеющих именем значение Adele.

В своём демонстрационном окружении я бы желал посмотреть список запрещённых учётных записей. Я могу сделать это следующей командой:


Get-AzureADUser -All $true -Filter 'accountEnabled eq false'
		

Мы можем изменить свой вывод и далее фильтруя получаемые сведения:


Get-AzureADUser -All $true -Filter 'accountEnabled eq false' | select DisplayName,UserPrincipalName,Department
		

Наша приводимая выше команда отобразит значения атрибутов DisplayName, UserPrincipalName и Department для отфильтрованных учётных записей.

В некой гибридной среде мы можем фильтровать синхронизированные с локальным AD учётные записи воспользовавшись следующим:


Get-AzureADUser -All $true -Filter 'DirSyncEnabled eq true'
		

В этой приведённой выше команде значение атрибута DirSyncEnabled определяет является ли учётная запись особенной только для облачного решения или синхронизируемой учётной записью.

Мы также можем проверить значение самой последней синхронизации для своих синхронизируемых учётных записей:


Get-AzureADUser  -All $true -Filter 'DirSyncEnabled eq true' | select DisplayName,UserPrincipalName,LastDirSyncTime
		

В нашей предыдущей команде значение LastDirSyncTime определяет время самой последней синхронизации указанного объекта.

Также мы обладаем возможностью экспорта получаемого вывода в некий CSV при помощи имеющейся команды Export-CSV:


Get-AzureADUser  -All $true -Filter 'DirSyncEnabled eq true' | select DisplayName,UserPrincipalName,LastDirSyncTime | Export-CSV -Path .\syncaccount.csv
		

Указываемое значение ImmutableID некой учётной записи пользователя применяется для установления соответствия объекта пользователя Azure AD с объектом пользователя на локальной площадке. ImmutableID не обладает никакой связью с ObjectGUID учётной записи пользователя на локальной площадке. Мы можем применять его лишь для идентификации только пользователей в облаке. Когда этот пользователь присутствует только в облаке, значением ImmutableID должно быть null:


Get-AzureADUser -All $true | where-Object {$_.ImmutableId -eq $null}
		

Приводимая выше команда возвратит перечень всех учётных записей, располагающихся только в облаке. При помощи приводимой далее команды мы можем выполнить экспорт всех необходимых значений атрибутов в CSV:


Get-AzureADUser -All $true | where-Object {$_.ImmutableId -eq $null} | select DisplayName,UserPrincipalName | Export-CSV -Path .\cloudaccount.csv
		

Другим важным моментом, имеющим отношение к учётным записям, являются лицензии. Если мы намерены воспользоваться премиальными функциональными возможностями Azur AD, нам необходимо обладать надлежащими выделенными лицензиями. В установках по умолчанию пользователь обладает лишь функциями свободно распространяемой версии Azure AD.

Для просмотра связанных с некой учётной записью лицензий мы можем применить такую команду:


Get-AzureADUserLicenseDetail -ObjectId MeganB@M365x562652.OnMicrosoft.com | fl
		

Наша приведённая выше команда возвратит те лицензии, которые привязаны к нашему пользователю MeganB@M365x562652.OnMicrosoft.com.

Мы также можем просмотреть SKU своих подписок при помощи следующей команды:


Get-AzureADSubscribedSku | fl
		

Приведённая выше команда перечислит все сведения относительно лицензий, связанных с данной арендой. Но по большей части, нам требуется лишь знать сколько лицензий применяется и сколько лицензий доступно. Мы можем выполнить это при помощи такой команды:


Get-AzureADSubscribedSku | select SkuPartNumber,ConsumedUnits -ExpandProperty PrepaidUnits
		

В приводимом примере значение SkuPartNumber представляет код компонента имеющейся лицензии. Получаемое значение разрешённого поля представляет собой общее число приобретённых лицензий. ConsumedUnits предоставляет общее число задействованных лицензий.

Давайте проследуем далее и рассмотрим как мы можем назначать какую- то новую лицензию некому пользователю.

В моей среде имеются два пользователя Azure AD, синхронизированных с локальной площадкой, которые не обладают назначенными им лицензиями:


Get-AzureADUserLicenseDetail -ObjectId ADJellison@M365x562652.onmicrosoft.com | fl
		

Приводимый ниже снимок экрана отображает вывод нашей предыдущей команды:

 

Рисунок 16-23



В качестве некого первичного этапа, давайте создадим объекты для их применения в процессе выделения соответствующей лицензии:


$newlicence = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newlicenceadd = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
		

Далее нам требуется отыскать значение SkuId для рассматриваемой лицензии.

Я намерен выделить такому пользователю имеющуюся лицензию ENTERPRISEPREMIUM:


$newlicenceadd.AddLicenses = $newlicence
		

После этого нам требуется назначить полученные лицензии соответствующему объекту:


$newlicence.SkuId = (Get-AzureADSubscribedSku | Where-Object -Property SkuPartNumber -Value "ENTERPRISEPREMIUM" -EQ).SkuId
		

Теперь мы способны проследовать далее и назначить эту лицензию надлежащему пользователю:


Set-AzureADUserLicense -ObjectId "ADJellison@M365x562652.onmicrosoft.com" -AssignedLicenses $newlicenceadd
		

Наша предыдущая команда выделяет лицензии ENTERPRISEPREMIUM нашему пользователю ADJellison@M365x562652.onmicrosoft.com:

 

Рисунок 16-24



[Замечание]Замечание

Необходимо устанавливать значение UsageLocation для тех пользователей, которые синхронизированы с AD локальной площадки перед выделением лицензий. Мы можем выполнить это при помощи Set-AzureADUser -ObjectId ADJellison@M365x562652.onmicrosoft.com -UsageLocation "US".

При помощи приводимой ниже команды мы имеем возможность удаления выделенных лицензий:


$licenseB = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$licenseB.RemoveLicenses =  (Get-AzureADSubscribedSku | Where-Object {$_.SkuPartNumber -eq 'ENTERPRISEPREMIUM'}).SkuId
Set-AzureADUserLicense -ObjectId "ADJellison@M365x562652.onmicrosoft.com" -AssignedLicenses $licenseB
		

При помощи приведённых выше команд я создал некий сценарий для осуществления следующего:

  • Поиска всех пользователей, синхронизированных с AD локальной площадки.

  • Из этих пользователей выбрать тех пользователей, которые не обладают выделенными им лицензиями Azure AD.

  • Установить значение атрибута UsageLocation для выбранных пользователей.

  • Для выбранных пользователей назначить лицензии Azure AD.


#######Script to Assign Licences to Synced Users from On-Permises AD#############
Import-Module AzureAD
Connect-AzureAD
###Filter Synced Users who doesn't have licence assigned#######
$ADusers = Get-AzureADUser -All $true -Filter 'DirSyncEnabled eq true'
$notlicenced = Get-AzureADUser -All $true | Where-Object {$ADusers.AssignedLicenses -ne $null} | select ObjectId | Out-File -FilePath C:\users.txt
#####Set UsageLocation value to sync users#########
(Get-Content "C:\users.txt" | select-object -skip 3) | ForEach { Set-AzureADUser -ObjectId $_ -UsageLocation "US" }
#####Set User Licecnes############
$newlicence = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newlicenceadd = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$newlicence.SkuId = (Get-
AzureADSubscribedSku | Where-Object -Property SkuPartNumber -Value "ENTERPRISEPREMIUM" -EQ).SkuId
$newlicenceadd.AddLicenses = $newlicence
(Get-Content "C:\users.txt" | select-object -skip 3) | ForEach { Set-AzureADUserLicense -ObjectId $_ -AssignedLicenses $newlicenceadd }
 	   

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

Воспользовавшись следующей командой, мы можем создать некого нового пользователя:


$Userpassword = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$Userpassword.Password = "London@1234"
New-AzureADUser -DisplayName "Andrew Xavier" -PasswordProfile $Userpassword -UserPrincipalName "Andrew.Xavier@M365x562652.onmicrosoft.com" -AccountEnabled $true -MailNickName "AndrewXavier"
		

В приводимой выше команде -PasswordProfile используется для определения значения пароля профиля для соответствующей учётной записи нового пользователя. -MailNickName определяет краткое имя в электронной почте данного пользователя. В нашем предыдущем примере добавлена учётная запись нового пользователя, Andrew.Xavier@M365x562652.onmicrosoft.com со значением пароля London@1234.

Применяя файлы CSV мы можем создавать множество учётных записей пользователей. В своём следующем примере для создания пользователей я пользуюсь неким файлом CSV. Это файл CSV содержит:


vfs.zfs.vdev.cache.size=<10M>UserPrincipalName, DisplayName,MailNickName
DishanM@M365x562652.onmicrosoft.com, Dishan Melroy,DishanMel
JackM@M365x562652.onmicrosoft.com,Jack May,JackMay
RicahrdP@M365x562652.onmicrosoft.com,Richard Parker,RichardPar
 	   

Затем применяя приводимое ниже я могу создать этих новых пользователей::


$Userpassword = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$Userpassword.Password = "London@1234"
Import-Csv -Path C:\newuser.csv | foreach {New-AzureADUser -UserPrincipalName $_.UserPrincipalName -DisplayName $_.DisplayName -MailNickName $_.MailNickName -PasswordProfile $Userpassword -AccountEnabled $true}
		

При помощи приведённых выше команд я создал сценарий для выполнения следующего:

  • Создания новых учётных записей при помощи файла CSV

  • Установки UsageLocation для учётных записей новых пользователей

  • Назначения пользователям лицензий ENTERPRISEPREMIUM


########A Script to create new users and assign Azure AD licences#######
Import-Module AzureAD
Connect-AzureAD
###########Create New Users using CSV ###################
$Userpassword = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$Userpassword.Password = "London@1234"
Import-Csv -Path C:\newuser.csv | foreach {New-AzureADUser -UserPrincipalName $_.UserPrincipalName -DisplayName $_.DisplayName -MailNickName $_.MailNickName -PasswordProfile $Userpassword -UsageLocation "US" -AccountEnabled $true} | select ObjectId | Out-File -FilePath C:\users.txt
###########Assign Licences#################
$newlicence = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$newlicenceadd = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$newlicence.SkuId = (Get-AzureADSubscribedSku | Where-Object -Property SkuPartNumber -Value "ENTERPRISEPREMIUM" -EQ).SkuId
$newlicenceadd.AddLicenses = $newlicence
(Get-Content "C:\users.txt" | select-object -skip 3) | ForEach { Set-AzureADUserLicense -ObjectId $_ -AssignedLicenses $newlicenceadd }
 	   

Для удаления некого пользователя Azure AD мы можем воспользоваться следующим:


Remove-AzureADUser -ObjectId "JDAllen@M365x562652.onmicrosoft.com"
		

Воспользовавшись приводимой далее командой мы можем объединить это с поиском пользователя:


Get-AzureADUser -Filter "startswith(DisplayName,'Dishan')" | Remove-AzureADUser
		

Наша предыдущая команды выполнит поиск учётных записей пользователей, обладающих DisplayName, которое начинается с Dishan. Если таковые имеются, вторая часть команды удалит их.

Управление группами

Группы Azure AD также работают схожим с локальными для AD группами образом. Их можно применять для управления полномочиями действенным способом. В некой гибридной среде будут иметься группы, применяемые только в облаке, а также группы, синхронизируемые с окружением AD локальной площадки. В этом разделе мы намерены рассмотреть управление группой при помощи модуля Azure Active Directory PowerShell for Graph.

Давайте начнём с перечисления групп. Мы можем найти некую группу воспользовавшись такой командой:


Get-AzureADGroup -SearchString "sg"
		

В приводимой выше команде SearchString используется для задания критерия поиска. Наш предыдущий пример перечислит все группы, содержащие sg в поле DisplayName:

 

Рисунок 16-25



В получаемых результатах поиска мы можем обнаружить значения ObjectId для искомых групп. При наличии известных ObjectId мы имеем возможность просмотра сведений об этих группах при помощи такой команды:


Get-AzureADGroup -ObjectId 93291438-be19-472e-a1d6-9b178b7ac619 | fl
		

В некой гибридной среде будут иметься группы безопасности, которые были синхронизированы с Active Directory локальной площадки. Применяя следующее, мы способны отфильтровать такие группы:


Get-AzureADGroup -Filter 'DirSyncEnabled eq true' | select ObjectId,DisplayName,LastDirSyncTime
		

В своём предыдущем примере, значения колонки LastDirSyncTime отображают время самой последней синхронизации соответствующей группы.

При помощи приводимой ниже команды мы можем отфильтровать группы, имеющиеся только в облаке:


Get-AzureADGroup -All $true | where-Object {$_.OnPremisesSecurityIdentifier -eq $null}
		

В приведённой команде для фильтрации таких групп мы воспользовались значением атрибута OnPremisesSecurityIdentifier. Этот атрибут обладает значением если он синхронизирован с AD локальной площадки.

Применяя следующее мы способны просмотреть участников группы:


Get-AzureADGroupMember -ObjectId 2a11d5ee-8383-44d1-9fbd-85cb4dcc2d5a
		

В своей предыдущей команде мы воспользовались ObjectId для уникальной идентификации интересующей нас группы.

При помощи cmdlet Add-AzureADGroupMember

мы имеем возможность добавления участников в указываемую группу:

Add-AzureADGroupMember -ObjectId 2a11d5ee-8383-44d1-9fbd-85cb4dcc2d5a -RefObjectId a6aeced9-909e-4684-8712-d0f242451338
		

В нашей приведённой выше команде значение ObjectId представляет рассматриваемую группу, а значение RefObjectId представляет добавляемого пользователя.

При помощи приводимой далее команды мы можем удалять участника из указанной группы:


Remove-AzureADGroupMember -ObjectId 2a11d5ee-8383-44d1-9fbd-85cb4dcc2d5a -MemberId a6aeced9-909e-4684-8712-d0f242451338
		

В приводимой команде значение ObjectId представляет выбранную группу, а значение MemberId представляет ObjectId соответствующего пользователя.

Мы также можем сочетать cmdlet Add-AzureADGroupMember с cmdlet Get-AzureADUser для добавления в некую группу пачки пользователей.

В своём следующем сценарии я воспользовался cmdlet Get-AzureADUser для поиска пользователей в Marketing Department, а затем применил Add-AzureADGroupMember для добавления этих пользователей к Sales Group в качестве участников:


#######Script to Add Multiple users to Security Group#############
Import-Module AzureAD
Connect-AzureAD
##### Search for users in Marketing Department ##########
Get-AzureADUser -All $true -Filter "Department eq 'Marketing'" | select ObjectId | Out-File -FilePath C:\salesusers.txt
#####Add Users to Sales Group#########
(Get-Content "C:\salesusers.txt" | select-object -skip 3) | ForEach { Add-AzureADGroupMember -ObjectId f9f51d29-e093-4e57-ad79-2fc5ae3517db -RefObjectId $_ }
 	   

В некой гибридной среде группы безопасности в основном синхронизируются их AD локальной площадки. Однако могут иметься также и требования для групп, располагающихся исключительно в облаке. При помощи следующего мы имеем возможность создания группы только для облака:


New-AzureADGroup -DisplayName "REBELADMIN Sales Team" -MailEnabled $false -MailNickName "salesteam" -SecurityEnabled $true
		

Приводимый ниже снимок экрана отображает получаемый в нашей предыдущей команде вывод:

 

Рисунок 16-26



Наша предыдущая команда создала некую группу безопасности с названием REBELADMIN Sales Team. Эта группа не является группой с включённым доступом через электронную почту.

при помощи своей следующей команды мы способны удалять группу Azure AD:


Remove-AzureADGroup -ObjectId 7592b555-343d-4f73-a6f1-2270d7cf014f
		

В приведённой выше команде значение ObjectId определяет удаляемую группу.

Помимо групп безопасности Azure AD также обладает предварительно заданными административными ролями, которые можно применять для назначения полномочий доступа к Azure AD и прочим облачным службам. Существует более 35 предварительно определённых административных ролей. Каждая из ролей обладает своим собственным набором полномочий. Дополнительные сведения об этих ролях можно найти на https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-assign-admin-roles.

Воспользовавшись следующей командой мы имеем возможность перечисления всех имеющихся административных ролей:


Get-AzureADDirectoryRoleTemplate
		

По умолчанию включёнными являются лишь несколько административных ролей. Воспользовавшись приводимой ниже командой мы можем вывести список этих ролей:


Get-AzureADDirectoryRole
		
[Замечание]Замечание

Здесь роль каталога администратора компании представляет соответствующих глобальных администраторов Azure AD.

Воспользовавшись следующим мы способны включать необходимую административную роль:


Enable-AzureADDirectoryRole -RoleTemplateId e6d1a23a-da11-4be4-9570-befc86d067a7
		

В нашей предыдущей команде значение RoleTemplateId представляет нужную нам административную роль.

Мы способны назначать выбранную административную роль некому пользователю применяя такую команду:


Add-AzureADDirectoryRoleMember -ObjectId b63c1671-625a-4a80-8bae-6487423909ca -RefObjectId 581c7265-c8cc-493b-9686-771b2f10a77e
		

В приведённой команде значение ObjectId представляет необходимую административную роль. RefObjectId является значением идентификатора объекта соответствующего пользователя.

При помощи своей следующей команды мы можем перечислять участников интересующей нас административной роли:


Get-AzureADDirectoryRoleMember -ObjectId 36b9ac02-9dfc-402a-8d44-ba2d8995dc06
		

В приводимой команде ObjectId представляет рассматриваемую нами административную роль.

Воспользовавшись командой внизу, мы имеем возможность удалять некого участника из указанной роли:


Remove-AzureADDirectoryRoleMember -ObjectId 36b9ac02-9dfc-402a-8d44-ba2d8995dc06 -MemberId 165ebcb7-f07d-42d2-a52e-90f44e71e4a1
		

В предыдущей команде MemberId эквивалентен значению идентификатора объекта удаляемого пользователя.

Это обозначает окончание данного раздела. Имеется великое множество cmdlet которые всё ещё можно применять для управления Azure AD, но здесь я дал пояснения лишь для тех cmdlet, которые необходимы для повседневных операций.

Выводы

PowerShell стал наиболее мощным языком сценариев для систем Windows. PowerShell является очень полезным для управления системами, но также может быть и невероятно мощным инструментом для управления инфраструктурами AD. На протяжении данной книги я применял PowerShell для настройки AD и управления им. Более того, я совместно применял различные команды и сценарии которые могут использоваться для действенного управления некой средой AD. Продвигаясь к окончанию данной главы вы изучили как реализовывать JEA и как его можно применять для защиты полномочий в неком окружении AD. Также мы изучили как управлять Azur AD с помощью имеющегося модуля Azure Active Directory PowerShell for Graph. В своей следующей главе мы рассмотрим Azure AD и изучим как управлять идентичностью в некой гибридной среде.