Powershell – параллельное выполнение операций – меняем настройки DNS


В современном (назовем его так) Powershell есть потрясающе удобная вещь – Workflow, которая позволяет выполнять работу параллельно (есть и другие приятности в Workflow, но сегодня только об этой).

Как мы делали раньше, если нужно опросить множество компьютеров в сети? Делаем в скрипте цикл и один за другим выполняем нужную операцию в отношении очередного по списку компьютера. Если компьютер отвечает медленно или вообще недоступен, скрипт останавливается, пока не истечет пауза и подключение к компьютеру не завершиться ошибкой. Для десятка компьютеров можно и потерпеть, а вот если их много, то приходилось что-то изобретать. Например, вставить в скрипт проверку доступности – обычный пинг – такая проверка завершается гораздо быстрее, чем неудачная попытка удаленного подключения по WMI. И наконец, если это нас не удовлетворяло, то скрипт переделывался так, чтобы запускать подпроцессы через Windows API или на крайний случай на Powershell собиралась конструкция порождения Jobs со всякими проверками, ограничениями и контролем завершения, чтобы не исчерпать ресурсы системы. Создавать и использовать такие сложные скрипты очень трудоемко, а задачи опроса множества компьютеров возникают постоянно.

Теперь это темное и ужасное прошлое! Теперь у нас есть возможность использовать механизм Workflow в Powershell.

Прежде всего надо сказать, что Workflow это не часть Powershell. Это очень важно понимать. Workflow это компонент Windows Workflow Foundation (WF) в .NET 4. Со стороны Powershell есть только интерфейс (хорошо интегрированный в языковые конструкции), который позволяет нам использовать нам возможности WF достаточно легко и просто.

Отсюда следует самая большая особенность работы с Workflow в Powershell: все очень похоже на Powershell, но это не Powershell – все работает сильно иначе. Все, что относится к Workflow, Powershell транслирует в подсистему WF, которая делает всю работу.  Если вы это поняли, то освоение Workflow пойдет у вас быстрее.

Следующий момент важный для понимания: в Workflow нет операций или командлетов – есть кое-что совершенно другое – activities или активности. В Powershell создано целое множество активностей, которые по написанию одинаковы с командлетами и делают тоже самое. Но еще раз отмечу – это не командлеты, а их эмуляция в WF. Поэтому далеко не все «командлеты» работают в Workflow – соответствующие активности не реализованы. Аналогичная ситуация с переменными: в Workflow это не переменные Powershell и ведут они себя по-своему.

Далее, следующая особенность. Все активности пишутся в Workflow последовательно, но выполняются одновременно и в произвольном порядке. Например, вы ходите опросить конфигурацию компьютера: вам достаточно перечислить в Workflow целый ряд нужных активностей (обращения к WMI), которые будут выполняться независимо и возвращать свой результат. Конечно есть конструкции языка, которые могут задавать последовательное выполнение активностей (установить приложение, перезагрузить компьютер, выполнить настройку приложения).

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

Вот пример скрипта, который использует эту возможность цикла Workflow и удаленно меняет настройки DNS на компьютерах, перечень которых задан в файле computerlist.txt:

workflow  wfSetDNS {

 

 param($computerName)

 

foreach -parallel($computer in $computerName) {

       inlinescript {if ((Get-WmiObject win32_networkadapterconfiguration -ComputerName $Using:computer.DNSHostName `

              -filter «ipenabled = ‘true'»).SetDNSServerSearchOrder(@(«172.0.0.10», «172.0.0.11»)).ReturnValue -eq 0 ) {«$($Using:computer.DNSHostName) — Ok»} else {«$($Using:computer.DNSHostName) — Error»}}

     }

 

}

 

$comps = Get-Content C:\computerlist.txt | % {$_.Trim()} | % { Get-ADComputer  $_ }

$comps = Get-ADComputer -Filter * -SearchBase «OU=Main,DC=domain,DC=ru»

wfSetDNS $comps

 

 

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

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

Напоследок отмечу, что Workflow могут выполняться точно так же как и скрипты Powershell либо локально, либо через подключение WSManagement удаленно. В приведенном примере Workflow выполняются локально на компьютере, где запущен скрипт, а удаленное подключение выполняется по WMI. Поэтому скрипт настраивает DNS на любых версиях Windows, где доступен соответствующий WMI интерфейс. В каких-то ситуациях Workflow нужно будет запускать непосредственно на целевом компьютере. В этом случае на нем нужно настроить WSManagement и установить .NET 4.

Реклама

комментария 4

  1. […] Powershell – параллельное выполнение операций – меняе… […]

  2. […] Powershell – параллельное выполнение операций – меняе… […]

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

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

Логотип WordPress.com

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

Фотография Twitter

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

Фотография Facebook

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

Google+ photo

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

Connecting to %s

%d такие блоггеры, как: