Вывод сообщения при прекращении работы процесса — Hey, Scripting Guy! Blog

В этом посте рассматривается встроенный класс WMI __InstanceDeletionEvent. Этот класс используется для отслеживания событий завершения работы процессов. Данный пост был написан для работы с Windows PowerShell 1.0, поэтому здесь рассматривается ручное создание экземпляра класса EventWatcher. Стоит упомянуть, что также существует класс Win32_ProcessStopTrace, при помощи которого решение задачи несколько облегчается. Цель этого поста- показать методы работы со встроенным классом WMI.

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

$dteStart = get-date
$total = 3
$monitorInterval = 5

Write-Host «Waiting for a process to be terminated …
You will be notified within $monitorInterval seconds of process termination
This script will monitor for $total occurences
start time was $dteStart»

$strQuery = «select * from __instanceDeletionEvent within $monitorInterval
where targetInstance isa ‘win32_Process'»

$objEventwatcher = New-Object management.managementEventWatcher $strQuery

for ($i = 1; $i -le $total ; $i++)
{$objEvent = $objEventwatcher.waitForNextEvent()
«$($objEvent.targetInstance.name) was terminated at $(Get-Date)»}

Первое, что мы делаем — это очищаем экран. при помощи функции Clear-Host. Так как это функция, вы можете увидеть ее код используя командлет Get-Content. Ниже приведен текст функции Clear-Host.

PS C:\AutoDoc> Get-Content Function:\Clear-Host
$spaceType = [System.Management.Automation.Host.BufferCell];
$space = [System.Activator]::CreateInstance($spaceType);
$space.Character = ‘ ‘;
$space.ForegroundColor = $host.ui.rawui.ForegroundColor;
$space.BackgroundColor = $host.ui.rawui.BackgroundColor;
$rectType = [System.Management.Automation.Host.Rectangle];
$rect = [System.Activator]::CreateInstance ($rectType);
$rect.Top = $rect.Bottom = $rect.Right = $rect.Left = -1;
$Host.UI.RawUI.SetBufferContents($rect, $space);
$coordType = [System.Management.Automation.Host.Coordinates];
$origin = [System.Activator]::CreateInstance($coordType);
$Host.UI.RawUI.CursorPosition = $origin;

Для ее вызова вы можете использовать либо ее имя — Clear-Host, либо алиас — cls. Однако лично я стараюсь не использовать алиасы, даже такие безобидные на вид как cls, так как вы не можете точно предсказать, что какой команде может быть назначен определенный алиас на других компьютерах.

Clear-Host

Далее мы используем командлет Get-Date для полечения текущих даты и времени и сохраняем полученный результат в переменной $dteStart.

$dteStart = get-date

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

Эти переменные задаются в следующих двух строках:

$total = 3
$monitorInterval = 5

Теперь нам нужно сообщить пользователям, что же скрипт собирается делать. Для этого мы используем командлет Write-Host. Мы используем двойные кавычки, так как это приводит к тому, что имя переменной, указанной в тексе при выводе заменяется на ее значение. Если бы мы использовали одинарные кавычки, то при выводе  мы бы получили строку точно в том виде, как она была задана — с именем переменной в тексте.

Write-Host «Waiting for a process to be terminated …
You will be notified within $monitorInterval seconds of process termination
This script will monitor for $total occurances
start time was $dteStart»

Далее нам нужно создать запрос события. Мы будем использовать класс __instanceDeletionEvent. Этот класс позволяем нам ослеживать события, когда что-либо удаляется. В качестве класса, удаление экземпляров которого мы будет отслеживать мы укажем Win32_Process. Таким образом, мы задаем, что, если какой-либо процесс прекратит свое существование — мы получим сообщение об этом событии. Естественно, мы можем использовать класс __instanceDeletionEvent и для отслеживания других классов.

$strQuery = «Select * from __instanceDeletionEvent within $monitorInterval where targetInstance isa ‘win32_Process'»

После того, как мы создали строку запроса, мы можем использовать командлет New-Object для создания экземпляра класса ManagamentEventWatcher. Для этого мы введем полное имя класса и в качестве аргумента укажем недавно созданную строку запроса. Созданный экземпляр класса System.Management.ManagentEventWatcher  мы сохраним в переменной $objEventWatcher.

$objEventwatcher = New-Object system.management.managementEventWatcher $strQuery

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

for ($i = 1; $i -le $total ; $i++)
{

Внутри цикла мы будем ожидать пока произойдет требуемое событие. Для этого мы воспользуемся методом WaitForNextEvent объекта ManagentEventWatcher. После того, как событие произойдет, этот метод возвратит нам объект класса ManagementBaseObject, который мы сохраним в переменной $objEvent. Затем мы выведем имя проесса и время получения события. Свойство targetInstance возвращенного объекта содержит в себе копию экземпляра Win32_Process. Таким образом, при необходмости мы можем получить значение любого свойству завершенного процесса.

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

$objEvent = $objEventwatcher.waitForNextEvent()
«$($objEvent.targetInstance.name) was terminated at $(Get-Date)»
}

После того, как скрипт пройдет заданное количество циклов, его работа завершится.

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

01

Авторы: Ed Wilson and Craig Liebendorfer, Scripting Guys

Оригинал: http://blogs.technet.com/b/heyscriptingguy/archive/2009/01/20/how-do-i-display-a-message-and-the-time-a-process-was-terminated.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. Выход /  Изменить )

Connecting to %s