Как стать автором
Обновить

Встречаем третий PowerShell (часть II)

PowerShell *
Продолжаем щупать нашими ненасытными пальчиками третий PowerShell. В прошлый раз мы сделали обзор новшеств и прикоснулись к нескольким дополнениям: попробовали командлет Show-Command, обкатали автоматическую подгрузку модулей, посмотрели на упрощенный языковой синтаксис и сконфигурировали файл сессии, попутно проделегировав пользователю сессии часть полномочий.

Scheduled jobs

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

(Get-Date).ToString() + " - начало выполнения" | Out-File "C:\logfile.txt" -Append
for ($i = 3; $i -lt 100; $i++)
{
    $flag = $true
    for ($j = 2; $j -lt $i; $j++)
    {
        if ($i % $j -eq 0) {$flag = $false}
    }
    if ($flag) {$i}
}
(Get-Date).ToString() + " - конец выполнения" | Out-File "C:\logfile.txt" -Append

Если не очень понятно, то блок внутри есть не совсем классическое решето Эратосфена: скрипт находит простые числа в диапазоне 3..100. Текст скрипта мы бережно сохраним в файл C:\ScheduledJob.ps1.
А теперь создаем нашу запланированную задачу:

$trigger = New-JobTrigger -Once -at 16:39
$job = Register-ScheduledJob -Name Job -FilePath "C:\ScheduledJob.ps1" -Trigger $trigger

Задача появляется в планировщике в ветке Task Scheduler Library/Microsoft/Windows/Powershell/ScheduledJobs:



Теперь дожидаемся наступления 16:39 и вуаля, в нашем logfile.txt появились строки:
24.06.2012 16:39:03 - начало выполнения
24.06.2012 16:39:04 - конец выполнения
А теперь самое интересное — для чего это все задумано? Ведь зашедулить задачу можно было и так: хоть скрипт, хоть не скрипт, хоть что угодно. А вот помните, что наша PowerShell-программка нам выводила простые числа? Запускаем еще одно окошко PowerShell и выполняем:

Import-Module PSScheduledJob
Get-Job
Receive-Job -Name Job

Получаем такую вот картинку:



Задача была выполнена, получен некоторый результат, этот результат был успешно сохранен в закромах PowerShell, а теперь мы этот результат из этих закромов просто извлекаем для своих целей, причем в промежутке между выполнением и извлечением можем перезагружаться, можем выполнять другие задачи, результат никуда не исчезнет. Это на самом деле приятная вещица, ведь можно отслеживать выполнение своих задач, в том числе и ошибки: к примеру, я могу заменить решето Эратосфена строкой 1/0 и после Receive-Job увижу Attempted to divide by zero, написанное красным шрифтом, что тоже не может не радовать глаз. Ну и чтоб поставить точку, я поделюсь адресом, где находятся названные мной закрома PowerShell: %userprofile%\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJobs, там располагается набор папок, xml файлов и идентификаторов со входными и выходными параметрами.

Robust sessions

Идея, как я понимаю, взята из Remote Desktop Services: установленная удаленная сессия сохраняется некоторое время при разрыве связи, и даже, в случае чего, ее можно восстановить с другой машины. Давайте посмотрим, как это делается, на w2012cl1 выполним:

New-PSSession -ComputerName w2012dc1 -Name RobustSession
Enter-PSSession -Name RobustSession
$x="abcdef123"

Таким образом, мы войдем в сессию и присвоим там некой переменной $x значение abcdef123, эту переменную мы будем использовать, чтобы проверять, та ли это сессия или нет, потерялись ли данные сессии или нет.
Теперь в настройках сетевой карты виртуальной машины делаем «ой!»:



И PowerShell на протяжении четырех минут пытается восстановить соединение:



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



И это еще не все фокусы, сейчас мы перехватим сессию, созданную на одной машине, с другой машины. На w2012cl1 производим действия:

$icptsess = New-PSSession -ComputerName w2012dc1 -Name InterceptedSession
Invoke-Command -Session $icptsess -ScriptBlock {$x="abcdef123"} #Отправляем команду в сессию
Disconnect-PSSession -Name InterceptedSession



Заостряю ваше внимание на том, что сессия перешла в состояние Disconnected, можем теперь к ней присоединиться с другой машины, w2012dc1 (да, тут я понимаю, эксперимент не слишком чистый, так как сессия на этой же машине, но мы будем использовать команды так, как будто она удалена):

$icptsess = Connect-PSSession -ComputerName w2012dc1 -Name InterceptedSession
Invoke-Command -Session $icptsess -ScriptBlock {$x}



И мы получаем сохраненную внутри сессии переменную на другой машине. Обратите внимание на командлет Invoke-Command, я им воспользовался, чтобы просто отправить внутрь сессии скриптовый блок, но теоретически мог бы войти в сессию с помощью Enter-PSSession и выполнить присвоение переменной значения внутри сеанса ровно так, как в первом примере.

Я хотел уместить все в две части, но следующая тема новшеств PowerShell, «Workflows» или «рабочие процессы», получается достаточно объемной сама по себе, поэтому я ее опишу отдельно в третьей части вместе с новинками оболочки PowerShell ISE. Ну и как бонус, в таком случае добавлю то, что не было заранее анонсировано, а именно доступ к PowerShell через Web: покажу, как командочки набирать прямо в браузере.
Теги:
Хабы:
Всего голосов 18: ↑13 и ↓5 +8
Просмотры 9.9K
Комментарии Комментарии 1