HEALTH WARNING: Be very careful cutting and pasting anything with quotes from here, other blog posts, word docs or emails as you may end up with an invalid quote in your notification template, preventing an email from being sent out at all.
There are some blogs out there on this (Thanks Travis ), but I struggled to find anything relating specifically to parent SRs which is one of the most common elements I find my customers want to include details from, when triggering a notification of a child activity going to in progress. And some of my customers have some cool customized SRs for purchase requests / new hire / employee termination process etc. and they want to include those custom properties from the parent SR (that were populated via prompts on the portal) in their activity notifications, and I found nothing on how to do that.
For example, lets say you have a new hire SR as described in my other post and then as part of the approval process, you want a notification to go out to the new employee’s manager, and include some specific properties from your custom SR class, to aid the hiring manager in approving the activity before Orchestrator goes off and does its various magic to create the user with the specified properties.
Before we continue, an alternative way to achieve this is to use orchestrator to put those entered values into a commonly available field (like title or description) and then in your SCSM notification template, just add Title or description. I’ve seen some customers use approaches like this to parse the user inputs (entered via request offering prompts in the portal) into the title or description.
However the focus of this blog is to explain how you can insert the values directly into a notification template.
We will focus on SR for now and getting the data from a parent SR into a child manual / review activity notification.
NOTE: Remember the notification template will be based off Manual Activity or Review Activity, because the subscription we will later create will trigger off a manual / review status changing from does not equals ‘In Progress’ changing to equals ‘In Progress’.
First things first is figuring out the relationship you need to use. This is best determined from the history tab of the child activity.
So for example if I look at a child manual activity within an SR, we can see the name of the relationship that associates the activity we’re looking at, to the parent SR is called ‘Contains Activity’
This helps us when we come to create the notification template in terms of picking the relationship as it narrows it down to two possibilities (not needed that second one to date so not sure what it is for ) :
NOTE: Keep reading on after the next paragraph as there’s a second step required to get this working
Once we pick the top ‘contains activity’ (it HAS to be the top one!!) then we can pick any of the values in the Work Item section on the right hand side which are values that are stored in the activity’s parent SR, so for instance description highlighted below is the SR description of the parent SR that contains the child manual activity.
If you pick the ID on the right rather than the description, you’ll end up with something like this shown in the notification template (WHICH DOES NOT WORK, SO PLEASE READ ON AFTER ).
CONTAINS ACTIVITY$Context/Path[Relationship='CustomSystem_WorkItem_Activity_Library!System.WorkItemContainsActivity' TypeConstraint='CustomSystem_WorkItem_Library!System.WorkItem']/Property[Type='CustomSystem_WorkItem_Library!System.WorkItem']/Id$
If you leave it like that, guess how it comes out in the email. It’s the big gaping space you see here under the second section where it says CONTAINS ACTIVITY:
The end result we want is the one shown below that which does show the Parent SR ID:
So how do we do that? The secret is in a seedrole. All you need to do is add this before the words TypeConstraint:
such that the old one which is this:
$Context/Path[Relationship='CustomSystem_WorkItem_Activity_Library!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CustomSystem_WorkItem_Library!System.WorkItem']/Property[Type='CustomSystem_WorkItem_Library!System.WorkItem']/Id$
This is how it looks in the template:
And then once you have that you can substitute ID for any of the values you see available under work item.
2nd HEALTH WARNING: The internal name (which is what you need to put in the template) may not be what you expect based on the display name. See below:
OK, great so far that we can add all these.
Now, what if I need something SR specific like area, Urgency, Priority, Support Group, Source, Implementation results, Implementation notes etc. Here’s that full list of possibilities:
Now we give ourselves a little more work to do
What we need to add is the Service Request class Internal name, the property internal name (not necessarily what you see in the table directly above), and the MP Alias referencing the MP containing the class definition. Here’s one way you can figure that out…
Create a notification template based on the class you’re trying to get properties for (like Service request) and then add one of the class specific properties using the insert button. You should end up with something like this:
This gives me the 3 pieces of information that I need – the MP alias, the class name, and the property name:
NOTE: Anything preceding a ‘!’ is an MP alias that should be found in the references section at the top of the MP where the alias is used.
So now going back to our manual activity notification template, we will start with the string we used to successfully get the Parent SR ID:
What we need to do is substitute the MP Alias, the class name and the property name.
$Context/Path[Relationship='CustomSystem_WorkItem_Activity_Library!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint=’MPAlias!ClassInternalName']/Property[Type=’MPAlias!ClassInternalName]/PropertyInternalName$
so the result is:
$Context/Path[Relationship='CustomSystem_WorkItem_Activity_Library!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CustomSystem_WorkItem_ServiceRequest_Library!System.WorkItem.ServiceRequest’]/Property[Type='CustomSystem_WorkItem_ServiceRequest_Library!System.WorkItem.ServiceRequest']/Area$
NOTE: You will also need to ensure the MP alias is included in the ‘references’ section of the MP that you’re creating the notification template in. One easy way to do this is create a template based on the class in the same MP that you’re crating your manual activity notification templates (even just temporarily and delete the template when you’re done as the reference will persist). In my case because I’m using the CustomSystem_workItem_serviceRequest_Library! MP Alias, I need to ensure the corresponding reference is in my MP where I’m storing my notification templates:
<Reference Alias="CustomSystem_WorkItem_ServiceRequest_Library"> <ID>System.WorkItem.ServiceRequest.Library</ID> <Version>7.5.2905.0</Version> <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> </Reference>
Now you can use the same string, but substitute the property internal name for other ones. Here’s that handy-dandy list of display names and ID names so you can substitute as needed:
So for example…
Here is how an extended SR looks in the authoring tool with that all important internal name shown (please click on the image to see it better):
So in that case, our class internal name is ClassExtension_65552f71_c29d_4438_827c_9db6015c10b0
The MP this is stored in is the CustomProps MP. Now we know this, we can create a template based on our extended class (in this case it will just be the OOB Service Request class), populate one of our custom properties with a value in the template, and then when I export the MP to XML (from Administration>Management Packs) I’ll get my reference:
<Reference Alias="CustomProps"> <ID>CustomProps</ID> <Version>188.8.131.52</Version> <PublicKeyToken>b7e405a08a89a054</PublicKeyToken> </Reference>
Now if I don’t want that template any more, I can just go ahead and delete the template, and my reference will persist.
So now we have our MP Alias and our Class Internal Name.
MP Alias – CustomProps
Class Internal Name - ClassExtension_65552f71_c29d_4438_827c_9db6015c10b0
The one last thing we need is out internal property Name which you can either find in the xml where your class is defined, or the authoring tool similarly to how we got the class name,
So in my case the end result is like this:
$Context/Path[Relationship='CustomSystem_WorkItem_Activity_Library!System.WorkItemContainsActivity' SeedRole='Target' TypeConstraint='CustomProps!ClassExtension_65552f71_c29d_4438_827c_9db6015c10b0']/Property[Type='CustomProps!ClassExtension_65552f71_c29d_4438_827c_9db6015c10b0']/ExtendedString1$
Using this approach you can include items from a parent SR (whether it be the OOB one, an extended one or an inherited one)
For completeness, I have included tables below for Incident and Change request Work Items (together with the SR and work item ones we saw earlier) as you might like to include these values in manual / review activity subscriptions where one of those is a parent item.
(and repeated from above):
Happy Subscribing! Cheers, Antoni
Another brilliant and well written up,what I have been looking for all along..........its a shame such small things are not built into the product. We as SCSM admins feel MS is not putting enough into the product compared to the other System Center products.
Thank you very much.
Great post Antoni!
Hey Sam, we hear you! The product team is focused on fixing the in-market issues around usability, perf, and scale with the product right now. These are areas which are crucial to the overall health of the product, and no matter way which way we cut it, a scalable,
performant and robust platform comes first. I think it's fantastic that we have the luxury of staying focused on the core of the product and rely on the community to come up with nifty solutions to fill in the application layer gaps.
If an MA is contained under a Parallel activity the code to display the PWI ID is actually displaying the PA's ID. Is there a work around for this?
Hi Anthony. To date I have only done this with orchestrator to do this extra hop. If I can figure out how to do it in a similar way to how I did it here, I will post an update. Cheers,Antoni