Skip to content

Сложные сценарии оповещения пользователей в SCSM

Сложные сценарии оповещения пользователей в SCSM published on 4 комментария к записи Сложные сценарии оповещения пользователей в SCSM

Из консоли SCSM мы можем настраивать рабочие процессы, которые будут реагировать на изменение свойств объекта. Такие рабочие процессы могут быть использованы для рассылки уведомлений при смене статуса, при изменении описания и так далее. У этого подхода есть один недостаток – мы не можем подписываться на изменение type projection, т.е. когда один объект связывается с другим. Примером таких свойств могут служить поля “Назначено на”, “Затронутый пользователь” (и вообще все поля типа “Пользователь или Группа”), а также “Затронутые услуги”, “Затронутые элементы” и т.д. При этом SCSM имеет встроенные механизм реагирования на такие события. Также мы не можем настраивать сложные условия для рассылки. О том, как задействовать оба этих механизма и пойдет речь в этой статье.

Но чтобы это сделать, необходимо понимать структуру пакетов управления SCSM. Т.к. схема практически идентична схеме пакетов управления OpsMgr, вы можете прочесть мою статью про пакеты управления OpsMgr, чтобы понимать о чем идет речь.

Для начала вкратце расскажу, что же происходит, когда мы создаем рабочий процесс из консоли SCSM. Для примера создадим просто рабочий процесс (РП) со следующими параметрами:

  • Объект: инцидент
  • Событие: изменение
  • Условие ДО: Состояние не равно Разрешен
  • Условие ПОСЛЕ: Состояние равно Разрешен
  • Применить шаблон: нет
  • Включить уведомление: Да
  • Пользователь: поле “Затронутый пользователь”

После создания РП в выбранном нами пакете управления создается правило (Rule), код которого приведен ниже (я опустил критерий, чтобы код был не очень большой)

juj
<Rule ID="WorkflowSubscription_7f8e18ce_d532_4d76_8788_f9b1cc063bb0" Enabled="true" Target="IncidentManagement!System.WorkItem.Incident.Wizard.AutomaticChangeIncident" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>System</Category>
<DataSources>
<DataSource ID="DS" TypeID="SystemCenter!Microsoft.SystemCenter.CmdbInstanceSubscription.DataSourceModule">
<Subscription>
<InstanceSubscription Type="a604b942-4c7b-2fb2-28dc-61dc6f465c68">
<UpdateInstance>
<Criteria>
<Expression>
.....вырезано.....
</Expression>
</Criteria>
</UpdateInstance>
</InstanceSubscription>
<PollingIntervalInSeconds>100</PollingIntervalInSeconds>
<BatchSize>50</BatchSize>
</Subscription>
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="WA" TypeID="SystemCenter!Microsoft.EnterpriseManagement.SystemCenter.Subscription.WindowsWorkflowTaskWriteAction">
<Subscription>
<EnableBatchProcessing>true</EnableBatchProcessing>
<WindowsWorkflowConfiguration>
<AssemblyName>Microsoft.EnterpriseManagement.ServiceManager.Incident.Workflows</AssemblyName>
<WorkflowTypeName>Microsoft.EnterpriseManagement.ServiceManager.Incident.Workflows.AutomaticIncidentChangeWorkflow</WorkflowTypeName>
<WorkflowParameters>
<WorkflowArrayParameter Name="InstanceIds" Type="guid">
<Item>$Data/BaseManagedEntityId$</Item>
</WorkflowArrayParameter>
<WorkflowParameter Name="NotificationRulesEnabled" Type="boolean">True</WorkflowParameter>
<WorkflowArrayParameter Name="NotificationTemplates" Type="guid">
<Item>0a152a9d-0739-921c-df13-845f76b9a467</Item>
</WorkflowArrayParameter>
<WorkflowArrayParameter Name="UserAliasOrRelationships" Type="string">
<Item>dff9be66-38b0-b6d6-6144-a412a3ebd4ce</Item>
</WorkflowArrayParameter>
</WorkflowParameters>
<RetryExceptions />
<RetryDelaySeconds>60</RetryDelaySeconds>
<MaximumRunningTimeSeconds>7200</MaximumRunningTimeSeconds>
</WindowsWorkflowConfiguration>
</Subscription>
</WriteAction>
</WriteActions>
</Rule>

В этом правиле присутствует источник данных (DataSource) типа Microsoft.SystemCenter.CmdbInstanceSubscription.DataSourceModule который как раз таки отвечает за подписку на события. Также источник отвечает за фильтрацию данных (секция Criteria, строка 8).

Атрибут Target (строка 1) данного правила задает тип объекта, для которого будет срабатывать правило. В нашем случае это инцидент.

Параметр PollingIntervalInSeconds определяет, как часто происходит постановка РП в очередь Workflow Service. Чем меньше это значение, тем больше растет очередь Workflow Service, что может негативно сказать на работе других РП. Но если у вас есть РП, события для которых происходит часто, стоит уменьшить это значение, но оставить его не менее 60 секунд. Следует обратить внимание, что этот параметр не устанавливает частоту опроса SCSM на предмет изменений.

В качестве WriteAction здесь указан модуль, который может применять шаблон к объекту иили отправлять оповещение. Т.к. при создании РП я выбрал только оповещение, в параметрах РП присутствует только атрибут “NotificationRulesEnabled”, который устанавливается в true (строка 31).

Параметр с атрибутом “NotificationTemplates” (строки 32-34) указывает ИД шаблона оповещения, который будет выбран для формирования сообщения. Список шаблонов можно получить с помощью PowerShell и командлет Get-SCSMObjectTemplate из состава cmdlet-ов для SCSM:

image

Соответственно, если нам необходимо узнать ID нужного шаблона уведомления, мы можем использовать этот же командлет:

Get-SCSMObjectTemplate | ? {$_.DisplayName -like "*оповещение при смене*"}| select ID, DisplayName

Параметр с атрибутом “UserAliasOrRelationships” (сроки 35-37) указывает ИД отношения, из которого будет браться пользователь. В данном случае это “Затрагиваемый пользователь”, в этом легко убедиться с помощью командлета Get-SCSMRelationshipClass:

image

Теперь мы знаем, что означает каждый из параметров, далее я покажу как использовать полученные знания.

Оповещения при любом смене статуса

Итак, представим, что нам необходимо оповещать пользователя о любом изменении статуса его инцидента. Стандартные параметры РП в консоли не позволяют нам сделать это, т.к. в параметрах мы можем задать только определенные значения статуса (правда мы можем создать РП для каждого изменения, но это не наш метод). Посмотрим на секцию критерия:

<Criteria>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<Property State="Pre">$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
</ValueExpression>
<Operator>NotEqual</Operator>
<ValueExpression>
<Value>{2b8830b6-59f0-f574-9c2a-f4b4682f1681}</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<Property State="Post">$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>{2b8830b6-59f0-f574-9c2a-f4b4682f1681}</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</Criteria>

Условие проверяет что данные ДО изменения (атрибут Pre в строке 7) не равны определенному состоянию, а после изменения (атрибут Post в строке 18) стал равен. Как вы помните, мы использовали статус Разрешен, убедимся в этом с помощью команд-лета Get-SCSMEnumeration:

image

Данное условие легко изменить на следующее: “Статус ДО” не равен “Статус ПОСЛЕ”.Сделаем необходимые изменения:

<Criteria>
<Expression>
<SimpleExpression>
<ValueExpression>
<Property State="Pre">$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
</ValueExpression>
<Operator>NotEqual</Operator>
<ValueExpression>
<Property State="Post">$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
</ValueExpression>
</SimpleExpression>
</Expression>
</Criteria>

Код стал в два раза меньше, а делать стал в два раза больше )) После изменения в пакете управления остается лишь импортировать его в SCSM поверх существующего.

Еще одно замечание. Вместо ИД элементов (классов отношений, шаблонов и пр.) мы можем использовать специальную конструкцию $MPElement[Name=””]$. В качестве имени необходимо использовать внутреннее имя элемента:

<!-- Вот как было -->
<Expression>
<SimpleExpression>
<ValueExpression>
<Property State="Post">$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>{2b8830b6-59f0-f574-9c2a-f4b4682f1681}</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<!-- Вот так стало -->
<Expression>
<SimpleExpression>
<ValueExpression>
<Property State="Post">$Context/Property[Type='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']/Status$</Property>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>$MPElememt[Name="CustomSystem_WorkItem_Incident_Library!IncidentStatusEnum.Resolved"]$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>

Внутреннее имя также можно получить с помощью PowerShell (см. пример с Get-SCSMEnumeration выше).

Но здесь следует иметь ввиду, что для получения объектов, расположенных в других пакетах управления (а это почти все объекты), необходимо верно указывать псевдоним(имя до знака !). Узнать, в каком пакете управления расположен элемент можно с помощью метода GetManagementPack:

image

Далее необходимо найти этот пакет в секции References (а если его там нет – то добавить), после чего скопировать Alias в MPElement (в нашем случаем это “CustomSystem_WorkItem_Incident_Library!”).

Оповещение при назначении или переназначении пользователя

Рассмотрим другой пример. Нам необходимо оповещать пользователя, когда на него назначается инцидент. Сделать это из консоли нельзя, а вот в XML – можно. Для этого нам необходимо поменять в модуле источника данных подписку (Subscription) c InstanceSubscription на RelationshipSubscription. Вот код подписки:

<DataSources>
<DataSource ID="DS" TypeID="SystemCenter1!Microsoft.SystemCenter.CmdbInstanceSubscription.DataSourceModule">
<Subscription>
<RelationshipSubscription RelType="$MPElement[Name='WorkItem!System.WorkItemAssignedToUser']$" SourceType="$MPElement[Name='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']$" TargetType="$MPElement[Name='System!System.Domain.User']$">
<AddRelationship>
</AddRelationship>
</RelationshipSubscription>
<PollingIntervalInSeconds>10</PollingIntervalInSeconds>
<BatchSize>100</BatchSize>
</Subscription>
</DataSource>
</DataSources>

Как видите мы использовали отношение System.WorkItemAssignedToUser, которое как раз таки и отвечает за свойство “Кому назначено”. Отношения можно получить с помощью командлета Get-SCSMRelationshipClass и части имени:

Get-SCSMRelationshipClass assigned | Select DisplayName, Name

Первый параметр –Name данного командлета ищет вхождение по принципу –like. Н-р можно найти отношения для “Затронутого Пользователя” (affected) и т.д.

Т.к. мы используем конструкцию MPElement, то в References нам надо добавить пакет управления System.WorkItem.Library и System.Library:

<Reference Alias="WorkItem">
<ID>System.WorkItem.Library</ID>
<Version>7.0.6555.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="System">
<ID>System.Library</ID>
<Version>7.0.6555.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>

Когда вы будете создавать свои  РП таким образом, проще всего создать РП с пустым критерием, указать нужный шаблон и поле пользователя, а затем уже отредактировать в XML только Subscription.

Внимательный читатель мог заметить, что в подписке используется только событие AddRelationship, как же быть с изменением? Дело в том, что при изменении отношения не происходит событие Update. Сначала происходит событие Remove, а затем Add. Это хорошо видно в Журнале:

image

Оповещение при добавлении “Затронутых элементов”

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

image

Теперь узнаем внутреннее имя и Target-класс:

image

Отредактируем подписку:

<DataSource ID="DS" TypeID="SystemCenter!Microsoft.SystemCenter.CmdbInstanceSubscription.DataSourceModule">
<Subscription>
<RelationshipSubscription RelType="$MPElement[Name='WorkItem!System.WorkItemAboutConfigItem']$" SourceType="$MPElement[Name='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']$" TargetType="$MPElement[Name='System!System.ConfigItem']$">
<AddRelationship />
</RelationshipSubscription>
<PollingIntervalInSeconds>10</PollingIntervalInSeconds>
<BatchSize>1</BatchSize>
</Subscription>
</DataSource>

Обратите внимание, что параметр BatchSize выставлен в 1. Дело в том, что если вы оставите его без изменений (50 по умолчанию), то пользователю придет ровно столько писем, сколько объектов было добавлено. Т.е. если мы добавим скажем сервер, диск и сетевое устройство, то пользователю придет 3 письма. BatchSize определяет, сколько объектов будет обработано в модуле.

В тексте шаблона мы можем использовать специальный тэг <group>, чтобы выводить список объектов:

Добрый день<br/>
<br/>
В инциденте $Context/Property[Type='WorkItem!System.WorkItem']/Id$ изменились затронутые конфигурационные элементы.<br/>
Список затронутых КЭ:<group>$Context/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem' TypeConstraint='System!System.ConfigItem']$?$DisplayName$?</group>
<br/>
<br/>
С уважением, служба поддержки.

В данном случае список будет выведен через точку с запятой.

Оповещение пользователя при добавлении комментария

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

image

image

Собственно код подписки:

<DataSource ID="DS" TypeID="SystemCenter!Microsoft.SystemCenter.CmdbInstanceSubscription.DataSourceModule">
<Subscription>
<RelationshipSubscription RelType="$MPElement[Name='WorkItem!System.WorkItem.TroubleTicketHasAnalystComment']$" SourceType="$MPElement[Name='CustomSystem_WorkItem_Incident_Library!System.WorkItem.Incident']$" TargetType="$MPElement[Name='WorkItem!System.WorkItem.TroubleTicket.AnalystCommentLog']$">
<AddRelationship>
</AddRelationship>
</RelationshipSubscription>
<PollingIntervalInSeconds>10</PollingIntervalInSeconds>
<BatchSize>1</BatchSize>
</Subscription>
</DataSource>

BatchSize также должен быть установлен в 1, т.к. за один раз может быть добавлено несколько записей.

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

Добрый день <br/> 
Записи в журнале аналитика: <br/>
<table border='1' cellspacing='0' >
<tr><td>Комментарий</td>
<td>Время</td>
<td>Кем добавлено</td>
</tr>
<Group>
<tr>
<td>
$Context/Path[Relationship='WorkItem!System.WorkItem.TroubleTicketHasAnalystComment' TypeConstraint='WorkItem!System.WorkItem.CommentLog']/Property[Type='WorkItem!System.WorkItem.CommentLog']/Comment$
</td>
<td>
$Context/Path[Relationship='WorkItem!System.WorkItem.TroubleTicketHasAnalystComment' TypeConstraint='WorkItem!System.WorkItem.CommentLog']/Property[Type='WorkItem!System.WorkItem.CommentLog']/EnteredDate$
</td>
<td>
$Context/Path[Relationship='WorkItem!System.WorkItem.TroubleTicketHasAnalystComment' TypeConstraint='WorkItem!System.WorkItem.CommentLog']/Property[Type='WorkItem!System.WorkItem.CommentLog']/EnteredBy$
</td>
</tr>
</Group>
</table>
<br/>
С уважением, служба поддержки.

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

image

Заключение

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

Поделиться в соц. сетях

Primary Sidebar