sergey vasin

The IT blog

PowerShell Workflows: Вопросы структуры – Hey, Scripting Guy! Blog

leave a comment »

Резюме: Microsoft PowerShell MVP и Honorary Scripting Guy 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: Используем параметры, рассказывается о параметрах рабочих процессов. Перед тем как читать эту статью, вам стоит ознакомиться с предыдущими.

Итак, Ричард.

Первый вопрос, который вы должны себе задать – «Что я собираюсь написать: рабочий процесс или обычный скрипт Windows PowerShell?»

Мой приятель MVP Don Jones написал отличную статью о том, когда вам стоит использовать рабочий процесс. Если же вкратце, то вам стоит использовать рабочие процессы, если:

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

Также приведу несколько потенциальных причин для использования рабочих процессов:

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

На самом деле, эти требования могут быть реализованы посредством скриптов или фоновых заданий (Jobs) Windows PowerShell. Одно из качеств, присущих эксперту по определенной технологии, это способность сказать, когда эта технология не должна использоваться. Так что не бойтесь сказать нет использованию рабочих процессов!

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

  1. Одновременное выполнение одного и того же задания на нескольких машинах
  2. Одновременное выполнение нескольких заданий на одной машине

В первом случае вы можете использовать как фоновые задания (Jobs), так и рабочие процессы (Workflows). Во втором случае вы определенно находитесь на территории рабочих процессов. Это туманное место.

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

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

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

Machine Operating system Windows PowerShell version
W12SUS Windows Server 2012 Windows PowerShell 3.0
Server02 Windows Server 2012 Windows PowerShell 3.0
WebR201 Windows Server 2008 R2 Windows PowerShell 2.0
Win7test Windows 7 Windows PowerShell 3.0

Создание ключа и записи реестра – это работа для WMI. Вы не думали, что я этого коснусь, ведь правда? На одной из машин установлен Windows PowerShell 2.0, поэтому вместо CIM-командлетов я буду использовать командлеты WMI. Причина этого в том, что командлеты CIM по умолчанию используют WSMan, но это должен быть WSMan v3.

Добавление ключа включает в себя следующее:

$hklm = 2147483650

$key = «SOFTWARE\HSGworkflowDEMO»

Invoke-WmiMethod -Class StdRegProv -Name CreateKey -ArgumentList $hklm, $key

Для создания записи потребуются дополнительные шаги:

$value = «AreYouThere»

$data = «Yes»

Invoke-WmiMethod -Class StdRegProv -Name SetStringValue -ArgumentList $hklm, $key, $data, $value

На случай, если вы удивляетесь порядку параметров, я запрошу командлет Get-CIMClass:

$class = Get-CimClass -ClassName StdRegProv

$class.CimClassMethods[«SetStringValue»]

$class.CimClassMethods[«SetStringValue»].Parameters

Вот что мы получим:

Name CimType Qualifiers

—- ——- ———-

hDefKey UInt32 {ID, IN}

sSubKeyName String {ID, IN}

sValue String {ID, in}

sValueName String {ID, in}

Если мы заглянем в документацию, то увидим, что sValueName находится перед sValue, что логично, но здесь командлет Invoke-WmiMethod ведет себя довольно странно и, по-видимому, ожидает, что параметры будут указаны в алфавитном порядке. В подобных случаях, если сомневаетесь, используйте порядок, указанный командлетом Get-CimClass.

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

  1. Указать параметр –ComputerName для каждого командлета Invoke-WmiMethod.
  2. Поместить код в скрипт-блок и запустить на удаленных компьютерах с помощью командлета Invoke-Command.

В каждом из случаев вы можете использовать параметр –AsJob.

Давайте рассмотрим второй вариант.

$sb = {

$hklm = 2147483650

$key = «SOFTWARE\HSGworkflowDEMO»

Invoke-WmiMethod -Class StdRegProv -Name CreateKey -ArgumentList $hklm, $key

$value = «AreYouThere»

$data = «Yes»

Invoke-WmiMethod -Class StdRegProv -Name SetStringValue -ArgumentList $hklm, $key, $data, $value

}

Invoke-Command -ComputerName server02, w12sus, win7test, webr201 -ScriptBlock $sb

Мы можем запустить все это в виде задания, добавив параметр –AsJob. В этом случае последняя строка будет выглядеть так:

Invoke-Command -ComputerName server02, w12sus, win7test, webr201 -ScriptBlock $sb –AsJob

В качестве небольшого наблюдения: я заметил, что команды на машинах с Windows PowerShell 3.0 выполняются быстрее, чем на компьютерах с Windows PowerShell 2.0.

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

workflow new-regkey {

$hklm = 2147483650

$key = «SOFTWARE\HSGworkflowDEMO»

Invoke-WmiMethod -Class StdRegProv -Name CreateKey -ArgumentList $hklm, $key

$value = «AreYouThere»

$data = «Yes»

Invoke-WmiMethod -Class StdRegProv -Name SetStringValue -ArgumentList $hklm, $key, $data, $value

}

Далее нам нужно будет запустить наш рабочий процесс, указав параметр –PSComputerName.

new-regkey -PSComputerName server02, w12sus, win7test, webr201

Пока что мы имели дело с простой задачей, которая может быт решена несколькими способами. Давайте все чуть-чуть усложним. Нашей задачей будет:

  • Создать ключ реестра HKLM:\SOFTWARE\HSGworkflowDEMO
  • Создать под этим ключом три записи и присвоить им значения:
    • AreYouThere = Yes
    • AreWeThereYet = No
    • PowerShell = 1

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

workflow new-regkey {

$hklm = 2147483650

$key = «SOFTWARE\HSGworkflowDEMO»

Invoke-WmiMethod -Class StdRegProv -Name CreateKey -ArgumentList $hklm, $key

parallel {

sequence {

$value = «AreYouThere»

$data = «Yes»

Invoke-WmiMethod -Class StdRegProv -Name SetStringValue -ArgumentList $hklm, $key, $data, $value

} # end of sequence

sequence {

$value = «PowerShell»

$data = 1

Invoke-WmiMethod -Class StdRegProv -Name SetDwordValue -ArgumentList $hklm, $key, $value, $data

} # end of sequence

sequence {

$value = «AreWeThereYet»

$data = «No»

Invoke-WmiMethod -Class StdRegProv -Name SetStringValue -ArgumentList $hklm, $key, $data, $value

}# end of sequence

}# end of parallel

}

Запускаем рабочий процесс.

new-regkey -PSComputerName server02, w12sus, win7test, webr201

Заметьте, как изменяется порядок аргументов командлета Invoke-WmiMethod во втором блоке sequence. Одна из загадок WMI.

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

Этот рабочий процесс можно разделить на следующие части:

  • Последовательное выполнение:
    • Создание ключа реестра
    • Параллельное создание трех записей реестра – двух строк и одного числового значения
      • Создание каждого значения происходит в три последовательных шага

Именно в такие моменты вы начинаете чувствовать удовольствие от использования рабочих процессов. А также приобретать опыт в их построении и в решении таких задач, как:

  • что должно выполняться параллельно, а что последовательно
  • какие потребуются переменные
  • взаимодействие между различными областями действия (scopes)

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

Что касается рабочих процессов, то ваше решение должно основываться на следующих факторах:

  • Какие задачи выполняет рабочий процесс?
  • В каком порядке эти задачи должны быть выполнены?
  • Можно ли что-то выполнить параллельно?
  • Нужно ли мне использовать блоки InlineScript?
  • Какие переменные мне понадобятся и где они должны быть определены?
    • Как на это повлияют области действия рабочего процесса?
  • Потребуется ли выполнение активностей рабочего процесса на удаленных машинах?
    • Будет ли он выполняться на локальной машине и обращаться к удаленным компьютерам или он будет запущен непосредственно на удаленных машинах с использованием возможностей удаленного выполнения команд?
    • Где будут указываться имена компьютеров – при вызове рабочих процессов, активностей или командлетов?
  • Что должно возвращаться по завершении рабочего процесса?
  • Потребуется ли перезагрузка компьютера в процессе выполнения рабочего процесса?
  • Потребуется ли сохранение состояний выполнения рабочего процесса?
    • Если да, то как часто?
  • Нужно ли сохранять какие-либо данные за пределами рабочего процесса?
  • Будет ли рабочий процесс запускаться в качестве задания?

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

На случай, если вы задумываетесь, как удалить созданные нами ключи реестра:

$sb = {

$hklm = 2147483650

$key = «SOFTWARE\HSGworkflowDEMO»

Invoke-WmiMethod -Class StdRegProv -Name DeleteKey -ArgumentList $hklm, $key

}

Invoke-Command -ComputerName server02, w12sus, win7test, webr201 -ScriptBlock $sb

Удалив ключ реестра, мы также удаляем все входящие в него ключи и записи.

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

~Richard.

Автор:

Ed Wilson, Microsoft Scripting Guy

Оригинал:

http://blogs.technet.com/b/heyscriptingguy/archive/2013/02/06/powershell-workflows-design-considerations.aspx


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

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


Реклама

Written by Сергей Васин

Март 26, 2013 в 09:46

Опубликовано в HeyScriptingGuyBlog, PowerShell

Tagged with ,

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

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

Логотип WordPress.com

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

Фотография Twitter

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

Фотография Facebook

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

Google+ photo

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

Connecting to %s