Working with relationships in the SCSM integration pack can be a bit tricky so this blog post is intended to provide some tips.
First of all it is really important when working with Service Manager to understand the data model. Have a look at the data model diagram that is included in the SM Job Aids package (more info) for details on what classes, properties and relationships exist in the out of box model. Keep in mind that the Orchestrator integration pack reflects this data model when you are configuring activities in a runbook. Another useful way to explore the data model is to use PowerShell (more info).
Secondly, if you haven’t already watched them I highly recommend watching these two demo videos that will provide you needed background info on automating service request fulfillment with SCSM and Orchestrator:
For the purposes of this blog post we will deal with a fairly common scenario when you are trying to automate service request fulfillment using SCSM (Service Catalog and Service Requests) and Orchestrator (runbooks). The scenario is adding the requesting user to a particular group in Active Directory.
The relevant part of the data model look like this (simplified):
The Runbook activity is going to kick off the Orchestrator runbook and it is going to pass a single piece of data to the runbook via the Initialize Data activity – the Runbook Activity Work Item GUID:
Configuration in Orchestrator:
Configuration in SCSM:
So – now when the runbook starts out it starts from the context of knowing exactly which Runbook Activity Work item triggered it. From there we can figure out which Group is related to it (i.e. the group that the requesting user should be added to).
We can also figure out the parent service request (see hyperlink above) and then we can traverse from the service request over to the Affected User.
So – our runbook looks like this at a high level:
This is what each activity does:
Initialize Data – takes in the runbook activity work item GUID as described above.
Get Group Relationship – this activity finds all the objects of a specific class that are related to the runbook activity work item – in this case the Active Directory Group class. The runbook activity work item GUID that is passed in via the Initialize Data activity is used as the starting point.
Get Group Object – this takes the output of the Get Group Relationship activity and actually gets the Group object itself using the related object GUID that is returned by the Get Group Relationship activity.
Let’s recap where we are….
Now we are going to do essentially the same thing to get the parent service request.
Get Parent SR Relationship – this activity gets the relationship between the Runbook Activity Work Item and the Service Request.
Get Parent SR – this activity actually gets the SR object using the output from the Get Parent SR Relationship activity.
OK – so let’s pause here and take a look at the configuration of each of these activities so far:
So far this should seem pretty straightforward. Now we are going to get a little bit tricky. The next thing we are going to do is traverse from the service request over to the affected user and get that object.
Get User Relationship – This activity gets the relationship between the service request and the affected user.
Get User Object – This activity gets the actual user object.
And the configuration dialogs:
Seems the same right? Not quite! There is a catch here.
Notice how in the Get Group Relationship configuration I pointed to the Active Directory Group class.
And in the Get User Relationship activity I pointed to the Active Directory User or Group class.
It’s really only conceivable for purposes of this scenario that the only Active Directory Groups that will be related to the Runbook Activity Work Item will be those which are related by the Work Item About Config Item relationship type.
In the case of the Service Request being related to the User class there are actually multiple relationship types between those two classes. In fact there are three in the out of the box data model:
Keep in mind that in the Get User Relationship activity the only configuration that I am providing is the source class (Service Request), source object GUID (Service Request GUID), and the target class (User). If the Created By User relationship points to Bob, the Assigned to Relationship points to Sally, and the Affected User points to Donna, how does Orchestrator know that I am looking for the Affected User Donna??
Here’s what happens. Orchestrator will grab all of the related objects that are of the User class that are related to the Service Request and put them on the databus as published data. If you open up the Runbook Tester and run this runbook you will see this in the output:
Those … mean that there is a collection of property values there not just one. If we double click on the … we can see the output in a table format:
So you can see in this case by looking at the Related Object GUID that the Affected User and the Created By User are the same user and the Assigned To User is a different user. Now – what we want to do is filter the list of objects that are passed along on the databus such that only the Affected User is passed along and everything else is dropped.
To do this we right click on the link coming out of the Get User Relationship activity and choose Properties:
Then click the Exclude tab and the Add button to add an Exclude filter. Click the first link and set it to Relationship Class, change the operator to ‘Does Not Equal’ and then click the last link and type in ‘Affected User’ (exactly as you see it above in the table).
This will now filter out the Assigned To User and Created By User and pass along only the Affected User on the databus.
That’s the trick! The rest is easy.
One more tip. As I showed you above you need to use the Display Name of the relationship type in question. You can discover the relationship type display name by using SMLets. First – look up the internal name in the Visio diagram of the data model linked to at the beginning of this blog post. For example the relationship type with the display name of ‘Affected User’ is called System.WorkItemAffectedUser. Then you can run a command in SMLets like this:
If you aren’t sure of the exact internal name of a relationship but you might have some idea of the word(s) that might be included you can do a quick search using part of the name using SMLets too: