Вы создали собственный класс, привязали к нему форму, отредактированную в Authoring Tool, и всё вроде бы замечательно. Но при попытке использовать форму в SCSM консоль падает, а в логе Operations Manager на компьютере, где запускается консоль, появляется ошибка “System.ArgumentException: propertyName”.
А происходит это потому, что SCSM как солдат в армии – выполняет ровно те приказы, которые ему отдают. И когда вы нацеливаете кастомизированную форму на класс, то SCSM при открытии формы загружает только свойства класса. Но обычно форма использует связанные объекты, к примеру связанные инциденты, создатель объекта, на кого назначено и т.д. И при попытке обратиться к этим связанным классам форма “падает”, т.к. SCSM их не загрузил.
Чтобы этого избежать, форма всегда (вернее, почти всегда – если форма не использует связанные классы, она может быть нацелена и на сам класс) должна быть нацелена не на сам класс, а на type projection (в русской версии консоли SCSM это называется “комбинированные классы”, далее используется сокращение TP). В этом случае при открытии формы будут загружать все связанные классы и форма сможет нормально работать.
Для того, чтобы это сделать, нужно посмотреть, на базе какого TP сделана изначальная форма и скопировать его. Сделать это можно и “руками” в базе данных, но это потребует несколько шагов, так что проще это сделать с помощью PowerShell и SMLets.
Следующий скрипт принимает на вход имя класса и выводит форму, которая связана с данным классом или любым из его TP. Также скрипт имеет параметр –ReturnTarget, который позволяет выводить класс или TP, на который нацелена форма (перед его вызовом необходимо импортировать модуль SMLets):
param([string]$className, [switch]$ReturnTarget) $cl = Get-SCSMClass -Name "$className$" $allIds = @{$cl.Id=$cl} $tps = Get-SCSMTypeProjection | ? {$_.TargetType -eq $cl} | % { $allIds.Add($_.Id, $_)} $form = Get-SCSMForm | ? { $allIds.Keys -contains $_.Target.Id} if($ReturnTarget) { return $allIds[$form.Target.Id] } else { return $form }
К примеру, вы создали новый класс на базе класса “Запрос на обслуживание”. Найдем форму для этого класса с помощью скрипта:
и в режиме –ReturnTarget:
Как видно, форма нацелена на ТР System.WorkItem.ServiceRequestProjection. Теперь нам необходимо скопировать определение этого TP в свой пакет управления. Для этого необходимо узнать, в каком пакете управления содержится TP. Почти все типы в SCSM поддерживают метод GetManagementPack(), поэтому узнать пакет также не сложно с помощью скрипта:
.\Get-SCSMFormByClassName.ps1 "System.WorkItem.ServiceRequest" -ReturnTarget | % {$_.__base.GetManagementPack()}
Обратите внимание, что сам тип при использовании SMLets “экранирован” и содержится в свойстве __base (впереди два символа подчеркивания). Вывод команды:
Пакет запечатан, поэтому у нас остается два пути: лезть в базу данных или использовать инструменты для экспорта данных из пакетов управления. Я предпочитаю первый путь. Запрос к БД будет выглядеть следующим образом:
USE ServiceManager SELECT MPName,MPFriendlyName, CONVERT(xml, MPXML), MPIsSealed FROM ManagementPack where MPName = 'ServiceManager.ServiceRequest.Library'
С помощью этого запроса вы можете прямо в SQL Managemetn Studio открыть XML-код и посмотреть содержимое пакета управления. Поиском строки “System.WorkItem.ServiceRequestProjection” находите определение TP и копируете его в свой пакет управления. После этого вам необходимо лишь вменить свойство Type для TP на имя вашего нового класса, дать новое имя (ID):
и изменить свойство Target для вашей формы на ID созданного TP.
спасибо большое :)
А как быть с языками?
Часть формы на русском остальная остальная часть на английском .
Влияние , срочность , источник и т.д на русском
Affected Services ,Affected Items, Affected user ,Assigned To и т.д на английском