Не всегда функционал "из коробки" пригоден в Заказчике, т.к. могут существовать определённые отличия бизнес процессов Заказчика от тех, которые видит себе разработчик продукта. К примеру, функционал согласования с подтверждением у линейного руководителя SCSM не всегда применим.
В одном из проектов нам пришлось реализовать сложный сценарий согласования, когда инициатор запроса сам выбирает утверждающего на портале SCSM 2012 R2.
По желанию Заказчика данная реализация должна была включать некий упорядоченный список "ДЕПАРТАМЕНТ->ОТДЕЛ->ФИО согласующего", в котором инициатор выбирает того, кто будет согласовывать запрос.
Для этого нами был создан скрипт ниже:
try
Import-Module SMlets
function WriteToLog($TextOut)
$CurrDateTime = Get-date -format 'u'
$CurrDateTime + " " + $TextOut | Out-file C:\CustomMPs\ScriptLog.log -append
$SR = Get-SCSMClass System.WorkItem.ServiceRequest$ | Get-SCSMObject -Filter "Displayname -like $srID*"
$TestOut = "Following SR discovered" + $SR + "with ID" + $srID
WriteToLog $TestOut
#Getting User input ReviwerID and looking for a Display name of this reviewer in Active Directory
$UserDN = $SR.ReviewerID.DisplayName
$TestOut = "Revewer Identified, reviewer name is:" + $UserDN
WriteToLog $TestOut
$User = Get-SCSMClass Microsoft.AD.User$ | Get-SCSMObject -Filter "Displayname -like $UserDN*"
$TestOut = "User DN is" + $User
WriteToLog $TestOut
$wiContainsActivity = Get-SCSMRelationshipClass System.WorkItemContainsActivity
#Trying to get raID, while it won't become available
While ($RA -eq $null)
{
WriteToLog $TestOut
#Setting up relationship
$Reviewer = Get-SCSMRelatedObject -SMObject $RA | ?{$_.ClassName -eq 'System.Reviewer'}
$reviewerIsUser = Get-SCSMRelationshipClass System.ReviewerIsUser
#Setting $User variable data as a Reviewer in RA
New-SCSMRelationshipObject -Relationship $reviewerIsUser -Source $Reviewer -Target $User -Bulk
Remove-Module SMlets -Force
catch
($_ | ConvertTo-XML).Save("C:\CustomMPs\ScriptLog.xml")
}
Данный скрипт является частью пакета управления, содержащего PowerShell активность, которая запускается по триггеру "на создание нового объекта класса запрос на обслуживание". Данный скрипт построен следующим образом:
1. Пользователь-инициатор, в списке на портале SCSM 2012 R2, выбирает согласующего, именование которого, совпадает с DisplayName в Active Directory;
2. Далее мы получаем ID объекта запрос на обслуживание с помощью переменной srID (тот запрос, который создал пользователь с помощью переменной скрипта в пакете управления);
3. Мы получаем наименование объекта Microsoft.AD.User в службе каталогов;
4. Далее выбираем все RA и пытаемся получить зависимость ReviewActivity до тех пор, пока нам это не удастся.
ПРИМЕЧАНИЕ! Такой подход вызван особенностью функционирования продукта: все компоненты запроса на обслуживания (активности, SLO и другие зависимые компоненты создаются не сразу, а постепенно, друг за другом). Если убрать данный цикл, то назначение рецензента не произойдёт.
5. После того, как мы получили активность согласования (рецензирования) производится назначение пользователя с помощью связи ReviewerIsUser.
Другие особенности скрипта:
Скрипт ведёт журналирование своей активности и ошибок с помощью методов try и catch, данные исключений выгружаются в XML файл, а так же содержит операционный лог успешных действий, заполняемый с помощью функции WriteToLog. Очень удобно для поиска проблем и отслеживания событий. Однако, думаю в продуктиве лучше отключить лог "успешных" действий.
Ограничения:
Нашли интересный баг/фитчу при попытке передать значение в $UserDN = $SR.ReviewerID , содержащее уже не DisplayName объекта ReveiwerID из списка enum, а значение строки, которую пользователь заполняет на портале (поле с форматом ввода string, привязанное к расширенному классу SR).
Из коробки не работает, несмотря на то, что вывод типа переменной, с помощью $User.GetType() в обоих случаях: значения списка (enum) $SR.ReviewerID.DisplayName и значения $SR.ReviewerID совпадает!!!
Выражается проблема в том, что не смотря на то, что поле с портала заполняется в SR, значение в срипте $SR.ReviewerID остаётся пустым, при этом формируется xml с ошибкой, что New-SCSMRelationshipObject -Relationship $reviewerIsUser -Source $Reviewer -Target $User -Bulk командлет не может быть выполнен.
Проблема решается явным приведением типа переменной, поступающей из поля с портала:
$SR.ReviewerID.ToString()
В одном из проектов нам пришлось реализовать сложный сценарий согласования, когда инициатор запроса сам выбирает утверждающего на портале SCSM 2012 R2.
По желанию Заказчика данная реализация должна была включать некий упорядоченный список "ДЕПАРТАМЕНТ->ОТДЕЛ->ФИО согласующего", в котором инициатор выбирает того, кто будет согласовывать запрос.
Для этого нами был создан скрипт ниже:
try
{
#Import SMlets
Import-Module SMlets
function WriteToLog($TextOut)
{
#This function creates and writes log file to the root partition of the "C Drive"
#Write-host $TextOut$CurrDateTime = Get-date -format 'u'
$CurrDateTime + " " + $TextOut | Out-file C:\CustomMPs\ScriptLog.log -append
}
#Getting srID of the brand new SR to work with
$SR = Get-SCSMClass System.WorkItem.ServiceRequest$ | Get-SCSMObject -Filter "Displayname -like $srID*"
$TestOut = "Following SR discovered" + $SR + "with ID" + $srID
WriteToLog $TestOut
#Getting User input ReviwerID and looking for a Display name of this reviewer in Active Directory
$UserDN = $SR.ReviewerID.DisplayName
$TestOut = "Revewer Identified, reviewer name is:" + $UserDN
WriteToLog $TestOut
$User = Get-SCSMClass Microsoft.AD.User$ | Get-SCSMObject -Filter "Displayname -like $UserDN*"
$TestOut = "User DN is" + $User
WriteToLog $TestOut
#Setting up relationship
$wiContainsActivity = Get-SCSMRelationshipClass System.WorkItemContainsActivity
#Trying to get raID, while it won't become available
While ($RA -eq $null)
{
$RA = Get-SCSMRelatedObject -SMObject $SR -Relationship $wiContainsActivity |? {$_.ClassName -eq 'System.WorkItem.Activity.ReviewActivity'
}
$TestOut = "SR contains RA:" + $RA
WriteToLog $TestOut
#Setting up relationship
$Reviewer = Get-SCSMRelatedObject -SMObject $RA | ?{$_.ClassName -eq 'System.Reviewer'}
$reviewerIsUser = Get-SCSMRelationshipClass System.ReviewerIsUser
#Setting $User variable data as a Reviewer in RA
New-SCSMRelationshipObject -Relationship $reviewerIsUser -Source $Reviewer -Target $User -Bulk
Remove-Module SMlets -Force
}
catch
{
# save variable to file
($_ | ConvertTo-XML).Save("C:\CustomMPs\ScriptLog.xml")
}
Данный скрипт является частью пакета управления, содержащего PowerShell активность, которая запускается по триггеру "на создание нового объекта класса запрос на обслуживание". Данный скрипт построен следующим образом:
1. Пользователь-инициатор, в списке на портале SCSM 2012 R2, выбирает согласующего, именование которого, совпадает с DisplayName в Active Directory;
2. Далее мы получаем ID объекта запрос на обслуживание с помощью переменной srID (тот запрос, который создал пользователь с помощью переменной скрипта в пакете управления);
3. Мы получаем наименование объекта Microsoft.AD.User в службе каталогов;
4. Далее выбираем все RA и пытаемся получить зависимость ReviewActivity до тех пор, пока нам это не удастся.
ПРИМЕЧАНИЕ! Такой подход вызван особенностью функционирования продукта: все компоненты запроса на обслуживания (активности, SLO и другие зависимые компоненты создаются не сразу, а постепенно, друг за другом). Если убрать данный цикл, то назначение рецензента не произойдёт.
5. После того, как мы получили активность согласования (рецензирования) производится назначение пользователя с помощью связи ReviewerIsUser.
Другие особенности скрипта:
Скрипт ведёт журналирование своей активности и ошибок с помощью методов try и catch, данные исключений выгружаются в XML файл, а так же содержит операционный лог успешных действий, заполняемый с помощью функции WriteToLog. Очень удобно для поиска проблем и отслеживания событий. Однако, думаю в продуктиве лучше отключить лог "успешных" действий.
Ограничения:
- Работает при наличии только одной активности рецензирования в запросе на обслуживание;
- Имя пользователя в списке на портале самообслуживания должно полностью совпадать с DisplayName пользователя в ActiveDirectory;
Нашли интересный баг/фитчу при попытке передать значение в $UserDN = $SR.ReviewerID , содержащее уже не DisplayName объекта ReveiwerID из списка enum, а значение строки, которую пользователь заполняет на портале (поле с форматом ввода string, привязанное к расширенному классу SR).
Из коробки не работает, несмотря на то, что вывод типа переменной, с помощью $User.GetType() в обоих случаях: значения списка (enum) $SR.ReviewerID.DisplayName и значения $SR.ReviewerID совпадает!!!
Выражается проблема в том, что не смотря на то, что поле с портала заполняется в SR, значение в срипте $SR.ReviewerID остаётся пустым, при этом формируется xml с ошибкой, что New-SCSMRelationshipObject -Relationship $reviewerIsUser -Source $Reviewer -Target $User -Bulk командлет не может быть выполнен.
Проблема решается явным приведением типа переменной, поступающей из поля с портала:
$SR.ReviewerID.ToString()