PowerShell Workflows: Пример практического использования – Hey, Scripting Guy! Blog

Резюме: Honorary Scripting Guy и Microsoft PowerShell MVP Richard Siddaway завершает свою серию статей о рабочих процессах Windows PowerShell. В этой статье разбирается один из примеров практического применения рабочих процессов.

Microsoft Scripting Guy, Ed Wilson на связи. Сегодня я публикую последнюю часть в серии статей о рабочих процессах Windows PowerShell за авторством Windows PowerShell MVP и Honorary Scripting Guy Richard Siddaway.

Заметка: Первая статья, PowerShell Workflows: Основы рассказывает об основных концепциях рабочих процессов. Вторая, PowerShell Workflows: Ограничения, рассматривает ограничения, с которыми вы можете столкнуться при написании рабочих процессов. Третья статья, PowerShell Workflows: Вложения, рассказывает о вложении рабочих процессов. В четвертой статье, PowerShell Workflows – Механизм заданий, рассказывается о запуске рабочих процессов в качестве заданий Windows PowerShell. В пятой статье, PowerShell Workflows: Перезагрузка компьютера, затрагиваются вопросы перезагрузки компьютера при выполнении рабочего процесса. В шестой статье, PowerShell Workflows: Используем параметры, рассказывается о параметрах рабочих процессов. В седьмой статье, PowerShell Workflows: Вопросы структуры, приводятся некоторые рекомендации по построению рабочих процессов. Перед тем как читать эту статью, вам стоит ознакомиться с предыдущими.

И опять, передаю слово Honorary Scripting Guy и Microsoft PowerShell MVP Richard Siddaway.

Это последняя статья в серии, касающейся рабочих процессов Windows PowerShell, однако это вовсе не значит, что писать о них я больше не собираюсь. Рабочие процессы – это новая концепция в Windows PowerShell, и, как и все нововведения, она требует глубокого тестирования для определения тех областей, где ее применение более всего обосновано.

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

Требуется выполнить следующие действия:

  1.  Создать родительское OU (организационное подразделение) для нового офиса
    1.  Создать дочернее OU пользователей
    2.  Создать дочернее OU компьютеров
  2. Создать UPN
  3. Создать учетные записи
    1. Создать 35 учетных записей компьютеров в компьютерном OU
    2. Создать 35 учетных записей пользователей в пользовательском OU
    3. Создать домашние каталоги
  4. Создать сайт Active Directory
    1. Создать Subnet (подсеть) и присоединить с сайту
    2. Создать Site Link (связь сайтов)
  5. Связать GPO
    1. Связать GPO (объект групповой политики) с OU пользователей
    2. Связать GPO (объект групповой политики) с OU компьютеров

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

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

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

Если вы представите список задач в виде псевдокода, подучится следующее:

workflow pseudocode {

parallel {

создать родительское OU

создать UPN

создать сайт AD

}

parallel {

sequence {

создать пользовательское OU

получить данные пользователей

parallel {

создать учетные записи пользователей

создать домашние каталоги

}

связать GPO с пользовательским OU

}

sequence {

создать компьютерное OU

получить данные компьютеров

parallel {

создать учетные записи компьютеров

}

связать GPO с компьютерным OU

}

sequence {

создать подсеть AD

создать связь сайтов AD

}

}

}

Начнем с блока parallel, создающего родительское OU, сайт AD и UPN. Все это можно выполнить параллельно, поскольку эти задачи никак не связаны друг с другом. Основная часть рабочего процесса состоит из блока parallel, содержащего три блока sequence – один для учетных записей пользователей, один для учетных записей компьютеров и один для задач топологии Active Directory. Внутри блоков sequence некоторые задачи выполняются параллельно, например, создание пользовательских учетных записей.

Хочу сказать, что структура, предложенная мной — это не единственный вариант построения рабочего процесса.

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

workflow new-location {

param (

[string]$locationname,

[string]$subnet

)

parallel {

New-ADOrganizationalUnit -Path «DC=manticore,DC=org» -Name $locationname

Set-ADObject -Identity «CN=Partitions,CN=Configuration,DC=manticore,DC=org» -Add @{upnsuffixes = «$locationname-manticore.org» }

New-ADReplicationSite -Name $locationname

}

parallel {

sequence {

New-ADOrganizationalUnit -Path «OU=$locationname,DC=manticore,DC=org» -Name «Users»

##

## получаем данные о пользователях

$password = ConvertTo-SecureString -AsPlainText -String «Pa55W0rd1!» -Force

$users = Import-Csv -Path ./userdata.csv

##

## создаем пользователей и домашние каталоги

foreach -parallel ($user in $users){

New-ADUser -AccountPassword $password -Name ($user.Lname + » » + $user.Fname) -Path «OU=Users,OU=$locationname,DC=manticore,DC=org» -SamAccountName $user.id -UserPrincipalName «$user.id@$locationname-manticore.org»

New-Item -Path «\\w12standard\home» -Name $user.id -ItemType Directory

}

##

## связываем GPO с пользовательским OU

New-GPLink -Name «Management Configuration» -Target «OU=Users,OU=$locationname,DC=manticore,DC=org»

}

##

## создаем компьютерное OU, учетные записи компьютеров и связываем GPO с OU

sequence {

New-ADOrganizationalUnit -Path «OU=$locationname,DC=manticore,DC=org» -Name «Computers»

$computers = 1..35

foreach -parallel ($computer in $computers) {

$cname = «$locationname-{0:000}» -f $computer

New-ADComputer -Path «OU=Computers,OU=$locationname,DC=manticore,DC=org» -Name $cname

}

New-GPLink -Name «W12Updates» -Target «OU=Computers,OU=$locationname,DC=manticore,DC=org»

}

sequence {

New-ADReplicationSubnet -Name $subnet -Site $locationname

New-ADReplicationSiteLink -Name «Site1-$locationname» -SitesIncluded «Site1», $locationname -InterSiteTransportProtocol IP -ReplicationFrequencyInMinutes 15

}

}

}

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

new-location -locationname Seattle -subnet «10.10.19.0/24»

Первое что делает рабочий процесс – создает родительское OU, сайт AD и UPN.

parallel {

New-ADOrganizationalUnit -Path «DC=manticore,DC=org» -Name $locationname

Set-ADObject -Identity «CN=Partitions,CN=Configuration,DC=manticore,DC=org» -Add @{upnsuffixes = «$locationname-manticore.org» }

New-ADReplicationSite -Name $locationname

}

Эти задачи могут быть выполнены параллельно. Они никак не зависят друг о друга, поэтому вы можете не беспокоиться о порядке их выполнения. Командлет New-ADReplicationSite появился в Windows Server 2012. Если в вашей среде он недоступен, вы можете видоизменить скрипт следующим образом:

$for = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()

$fortyp = [System.DirectoryServices.ActiveDirectory.DirectoryContexttype]»forest»

$forcntxt = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext($fortyp, $for)

## создание нового сайта

$site = new-object System.DirectoryServices.ActiveDirectory.ActiveDirectorySite($forcntxt, «MyNewSite2»)

$site.Save()

Вам потребуется запустить это код в блоке InlineScript.

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

sequence {

New-ADOrganizationalUnit -Path «OU=$locationname,DC=manticore,DC=org» -Name «Users»

##

## получаем данные о пользователях

$password = ConvertTo-SecureString -AsPlainText -String «Pa55W0rd1!» -Force

$users = Import-Csv -Path ./userdata.csv

##

## создаем пользователей и домашние каталоги

foreach -parallel ($user in $users){

New-ADUser -AccountPassword $password -Name ($user.Lname + » » + $user.Fname) -Path «OU=Users,OU=$locationname,DC=manticore,DC=org» -SamAccountName $user.id -UserPrincipalName «$user.id@$locationname-manticore.org»

New-Item -Path «\\w12standard\home» -Name $user.id -ItemType Directory

}

##

## связываем GPO с пользовательским OU

New-GPLink -Name «Management Configuration» -Target «OU=Users,OU=$locationname,DC=manticore,DC=org»

}

Создается OU для пользовательских учетных записей. В нескольких местах кода мы ссылаемся на переменную locationname. Она определена в более высокой области действия (scope), но так как мы используем ее в блоках parallel и sequence, то нам нужно просто указать ее имя.

Также мы задаем пароль для учетной записи пользователя. И нет, я не стал бы это использовать в промышленной среде. Я бы указал пароль в качестве еще одного параметра. Никогда не указывайте пароли в тексте скрипта!

Информация о пользователе получается из файла CSV. В нашем случае файл содержит имя, фамилию и идентификатор пользователя. Вы можете добавить необходимые данные и задействовать еще несколько параметров командлета New-ADUser. Если вы не обладаете опытом использования данного командлета, я бы посоветовал вам обратиться к файлу справки, чтобы узнать, что с его помощью можно сделать. Странность заключается в способе задания имени пользовательской учетной записи – подстановка строк не работает, кроме того в рабочих процессах вы не можете использовать подвыражения.

Я указал имя файла явным образом, но вы можете это изменить. Как вам идея использовать механизм событий Windows PowerShell для наблюдения за определенным каталогом? Как только в него попадает новый файл, срабатывает событие и запускается рабочий процесс! Это привнесет еще большую степень автоматизации.

Создание учетных записей пользователей происходит с использованием конструкции foreach –parallel. Она ужасающе мощная. В нашем случае создание 35 учетных записей происходит параллельно. Создание учетной записи и домашнего каталога происходит последовательно, но эти действия происходят параллельно для 35 разных пользователей. Попробовать предположить, чем именно занимается рабочий процесс в определенный момент времени – интересная задача. Мне кажется, это возможно только в том случае, если вы добавите с рабочий процесс механизм журналирования.

Последнее, что выполняется в этом блоке sequence – это связывание GPO с пользовательским OU.

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

sequence {

New-ADOrganizationalUnit -Path «OU=$locationname,DC=manticore,DC=org» -Name «Computers»

$computers = 1..35

foreach -parallel ($computer in $computers) {

$cname = «$locationname-{0:000}» -f $computer

New-ADComputer -Path «OU=Computers,OU=$locationname,DC=manticore,DC=org» -Name $cname

}

New-GPLink -Name «W12Updates» -Target «OU=Computers,OU=$locationname,DC=manticore,DC=org»

}

Сначала создается OU, затем в нем создаются 35 учетных записей компьютеров. Для простоты я явным образом указал их имена, но вы можете использовать для этого отдельный параметр. Кроме того, вы можете подсчитать число создаваемых учетных записей пользователей и создать по одной учетной записи компьютера на каждого пользователя.

Я использую форматирование строк, чтобы создать имя компьютера, отвечающее правилам именования компьютеров в организации. Затем оно передается командлету New-ADComputer. И снова, чтобы воспользоваться преимуществами параллельного выполнения, я использую конструкцию foreach –parallel.

Далее мы используем командлет New-GPLink для связи GPO с компьютерным OU.

Последний блок sequence вносит изменения в топологию Active Directory.

sequence {

New-ADReplicationSubnet -Name $subnet -Site $locationname

New-ADReplicationSiteLink -Name «Site1-$locationname» -SitesIncluded «Site1», $locationname -InterSiteTransportProtocol IP -ReplicationFrequencyInMinutes 15

}

Эти два командлета доступны только в Windows Server 2012. Если в вашей среде используются серверы более ранних версий, вы можете заменить их следующими командами.

Создание подсети:

## получаем объект леса и задаем контекст именования

$for = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()

$fortyp = [System.DirectoryServices.ActiveDirectory.DirectoryContexttype]»forest»

$forcntxt = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext($fortyp, $for)

$site = «MyNewSite2»

$subnetlocation = «Building X»

$subnetname = «10.55.0.0/24»

## создаем подсеть и присоединяем к сайту

$subnet = New-Object System.DirectoryServices.ActiveDirectory.ActiveDirectorySubnet($forcntxt, $subnetname, $site)

$Subnet.Location = $subnetlocation

$subnet.Save()

Создание связи сайта:

## получаем объект леса и задаем контекст именования

$for = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()

$fortyp = [System.DirectoryServices.ActiveDirectory.DirectoryContexttype]»forest»

$forcntxt = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext($fortyp, $for)

$link = New-Object -TypeName System.DirectoryServices.ActiveDirectory.ActiveDirectorySiteLink -ArgumentList $forcntxt, «MyNewSite3-MyNewSite4»

$site1 = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::FindByName($forcntxt, «MyNewSite3»)

$site2 = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::FindByName($forcntxt, «MyNewSite4»)

$link.Sites.Add($site1)

$link.Sites.Add($site2)

$link.Cost = 150

$link.ReplicationInterval = «01:00:00» ## 1 час 24×7

$link.Save()

$linkde = $link.GetDirectoryEntry()

$linkde.Description = «Links sites MyNewSite3 and MyNewSite4»

$linkde.SetInfo()

Этот код нужно будет поместить в блок InlineScript. И помните, вам для доступа к переменным, определенным в верхних областях действия (scope), вам нужно использовать модификатор Using.

Я надеюсь, что эта серия статей показала вам мощь рабочих процессов и то, как их можно использовать. Рабочие процессы – это очень полезный ресурс, с которым сообщество Windows PowerShell еще только начало разбираться. Эта серия – всего лишь шаг к пониманию принципов их работы, поэтому я советую вам не останавливаться и продолжать экспериментировать с ними. Также не забывайте делиться результатами с остальной частью сообщества. Со мной вы можете связаться через мой блог.

Я не думаю, что это последнее мое слово о рабочих процессах, так что – до новых встреч.

~Richard.

Автор:

Ed Wilson, Microsoft Scripting Guy

Оригинал:

http://blogs.technet.com/b/heyscriptingguy/archive/2013/02/13/powershell-workflows-a-practical-example.aspx


Страницы в социальных сетях:

Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell


Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

w

Connecting to %s