Windows PowerShell: Создаем что-то, похожее на рабочий процесс

OSzone.net » Microsoft » PowerShell » Windows PowerShell: Создаем что-то, похожее на рабочий процесс
Автор: Дон Джонс
Иcточник: TechNetMagazine
Опубликована: 25.06.2013

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

Вы всегда должны помнить, что Windows PowerShell приходится преобразовывать рабочие процессы в код совершенно другой технологии — Windows Workflow Foundation (WF). Это означает, что вы можете делать только то, что можно продублировать в WF. Затем ваш код будет выполняться в совершенно другой среде со своими собственными правилами и ограничениями.

Запуск любого сценария как рабочего процесса

Самый простой способ попробовать выполнить рабочий процесс — просто выполнить любой стандартный сценарий Windows PowerShell как рабочий процесс. Это можно сделать командой Invoke-AsWorkflow. Она находится в модуле PSWorkflow, хотя Windows PowerShell версии 3 способна обнаруживать и запускать команды, не требуя, чтобы вы сначала явно загружали модуль. Эта команда обязательно обертывает весь ваш сценарий блоком InlineScript, значит, он выполняется в WF как одна операция.

Следовательно, можно не беспокоиться насчет ограничений Windows PowerShell Workflow. Однако вы не сможете и воспользоваться кое-какими функциями Windows PowerShell Workflow, например, возможностью возобновить прерванный процесс. «Процесс» в вашем случае будет состоять из одного этапа, на котором выполняется весь сценарий. Будет невозможно возобновить выполнение рабочего процесса, если потребуется приостановить или прервать его на полпути. Вот вам пример, в котором я создаю блок сценария с несколькими командами, а затем выполняю их как рабочий процесс:

$script = {
  $name = Get-Content Env:\COMPUTERNAME
  $name | Out-File c:\MyName.txt
  Get-Service
}
Invoke-AsWorkflow -Expression $script -PSComputerName DC,CLIENT

Одна из причин того, что я воспользовался переменной, — желание продемонстрировать, что WF выполняет все эти команды как один InlineScript. Имейте в виду, что каждая команда WF выполняется в своей собственной, созданной заново среде. В ней нет встроенных механизмов сохранения данных между командами. Это значит, что от самих по себе переменных довольно мало толку. Однако, поскольку у нас происходит неявное обертывание всех команд одноэтапным InlineScript, созданная мной переменная будет передаваться между командами.

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

Формальный синтаксис рабочих процессов

Вот очень простой рабочий процесс:

Workflow New-Server {
    Get-Content -Path Env:\COMPUTERNAME |
    Out-File -FilePath C:\MyName.txt
 Get-NetAdapter -Physical
}
New-Server -PSComputerName CLIENT,DC

Рабочие процессы — разновидность команд Windows PowerShell, как и командлеты, сценарии и функции. Таким образом, вы можете запускать их, просто указывая имя, как я и сделал в последней строке своего примера. Помните, что все рабочие процессы наследуют кое-какие встроенные параметры, такие как –PSComputerName. Кроме того, рабочие процессы опираются на функциональность Windows PowerShell Remoting, которая в моем примере должна быть активна на обоих компьютерах.

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

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

Теперь давайте рассмотрим другой рабочий процесс (заметьте, что вам придется импортировать сеанс PSWorkflow в свой экземпляр оболочки, чтобы ключевое слово Workflow стало допустимым):

Workflow New-Server {
 $name = Get-Content -Path Env:\COMPUTERNAME
    Get-Content -Path Env:\COMPUTERNAME |
    Out-File -FilePath C:\MyName.txt
  Get-NetAdapter -Physical
  $name | Out-File -FilePath C:\MyOtherName.txt
}
New-Server -PSComputerName CLIENT,DC

Как только я написал этот пример, я подумал: «Файл MyOtherName.txt будет пустым». Вспомните: каждая часть рабочего процесса выполняется как отдельная команда, у них общего контекста. Однако когда я запустил свой пример, он отработал корректно. Как ни странно, имя компьютера записалось и в MyName.txt, и в MyOtherName.txt. Что же произошло?

В Windows PowerShell выполняется, в самом деле, огромная закулисная работа, направленная на то, чтобы вы получали от рабочего процесса ожидаемые результаты. Например, «обычная» команда рабочего процесса написана весьма специфическим образом. WF не имеет встроенных аналогов для абсолютно всех командлетов Windows PowerShell. Группа разработки Windows PowerShell реализовала WF-эквиваленты для огромного списка встроенных командлетов, поэтому часто оказывается, что командлеты и операции WF находятся в отношении «один к одному».

Когда вы используете командлет, для которого нет соответствующей операции, Windows PowerShell неявно обертывает ваш код операцией WF InlineScript. В результате WF запускает Windows PowerShell, выполняет вашу команду в Windows PowerShell, а затем возвращает результаты в WF. Поэтому оказывается, что много кода, который «не должен» работать, работает, поскольку Windows PowerShell «доводит его до ума».

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

Куда мы двинемся дальше

Верите или нет, но вы уже можете приступать к написанию простейших рабочих процессов. Вы можете использовать в качестве их адресата любой компьютер, на котором установлена Windows PowerShell версии 3 и активизирован Remoting. Одна из причин, по которым нужна активизация Remoting, — то, что при этом создается конфигурация сеансов, используемая Windows PowerShell Workflow. Если вы активизировали Remoting на компьютере с Windows PowerShell версии 2, а затем установили версию 3, потребуется снова запустить Enable-PSRemoting для создания необходимой конфигурации.

Старайтесь особо не усложнять свои рабочие процессы. Выполняйте последовательность команд и не предпринимайте множество хитрых маневров. У вас не должно возникнуть никаких проблем, и при этом вы сможете воспользоваться встроенными возможностями Windows PowerShell Workflow, поддержкой нескольких компьютеров-адресатов и другими функциями.

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


Ссылка: http://www.oszone.net/21367/