Welcome to Day 28 of the “100 Days of DevOps with PowerShell”! For background on our goals in this series, see Announcing the “100 Days of Devops with PowerShell” Series here at SCC.
In my previous posts, I’ve discussed how to use PowerShell to create work items in both Team Foundation Server and System Center Service Manager 2012. In this post, I’m going to build off the PowerShell code from “Day 13: PowerShell and Team Foundation Server 2013 – Using the TFS API” to automatically create a Task work item in Team Foundation Server, when a certain type of Incident is created in Service Manager.
To do this, I am going to create a custom Service Manager PowerShell workflow, using the Service Manager Authoring Tool. This PowerShell workflow will use the script from Day 13. However, before I can do that, I need to install some pre-reqs on the Service Manager Management Server.
First, I need to install Team Explorer 2013, so that the TFS API will exist on the management server. I downloaded Team Explorer and ran the standard installation. After installing Team Explorer, I then installed the Microsoft Visual Studio Team Foundation Server 2013 Power Tools Update 2.
Finally, I added the Service Manager workflow account as a user to the Team Foundation Server Team Project I am using. This gives the account the ability to create work items in the Team Project. I did this by opening the Team Project in Team Explorer, selecting Project Settings, and then Security. This opens a web page where I can add new members to the team.
After adding the workflow account to the team, I wanted to make sure I could create work items from the Service Manager Management Server. I opened the PowerShell ISE as the workflow account and ran the script from Day 13. A Task work item was created successfully in TFS. At this point, it looks like the workflow account has the correct permissions, and all the necessary pre-reqs are installed on the Service Manager Management Server.
Creating the SCSM Workflow
Now I need to create a Service Manager PowerShell workflow, that executes the script from Day 13. This requires creating a custom management pack for Service Manager, using the Service Manager Authoring Tool. You can download the authoring tool for free from here. My criteria is that whenever a new Incident with a classification category of Software Problems is created, I want to automatically create a Task work item in Team Foundation Server.
Open the Authoring Tool and select File | New to create a new management pack: TFS.Integrations.xml. In the Management Pack Explorer window, right-click on Workflows, and select Create.
This opens the Create Workflow Wizard. On the General tab of the wizard, enter the name of your workflow.
On the Trigger Condition tab, select Run only when a database objects meets specified conditions.
Select the Incident class, using the Browse button. Make sure the Change Event is When an object of the selected class is created. Then click the Additional Criteria button.
For additional criteria, select the Classification Category and set it equal to Software Problems. This ensures that only New Software Problem Incidents will create a task in TFS.
Click Create to create the workflow, and then Close to exit the wizard. At this point, I have a new Windows Workflow with no activities.
From Script Activities | General Script Activities, drag a Windows PowerShell Script Activity onto the workspace. In the details window, change the name of the activity to be CreateTFSTaskFromNewIncident. Then, in the Details window, select Script Parameters, and click the ellipse button. This opens the Configure a Script Activity. Click the Script Properties tab. This is where I can get values from the incident that triggers the workflow and use those values in our PowerShell.
I want to get the Incident ID, Incident Title, and Incident Description, so I can store them in the TFS Task.
Click the New button. This adds a new row to the properties window. In the name field, enter IncidentId. Now click the gray button next to the Value field. This allows you to select a property from the class that triggered the workflow to run. Select the ID property and click OK.
I now have a script parameter named IncidentID that returns the ID of the incident that triggers the workflow.
Following the same instructions as above, create parameters for IncidentTitle and IncidentDescription.
With the parameters in place, I can now create the PowerShell script. Click the Script Body tab.
I’m going to use the script from Day 13, with a couple of tweaks:
#Load TFS PowerShell Snap-in
if ((Get-PSSnapIn -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null)
#Load Reference Assemblies
#TFS Server Collection
[string] $tfsCollectionUrl = "http://r2-09-tfs:8080/tfs/DefaultCollection"
#Get Team Project Collection
$teamProjectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($tfsCollectionUrl)
#Get Work Item Store object
$ws = $teamProjectCollection.GetService([type]"Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore")
#Get Team Project
$proj = $ws.Projects["TestTeamProject"]
#Get the Work Item Type to create
$wit = $proj.WorkItemTypes["Task"]
#Create a new work item of that type
$workitem = $wit.NewWorkItem()
#Set work item properties
$workItem.Title = "$IncidentTitle"
$workItem.Description = "$IncidentId : $IncidentDescription"
$workitem.AreaPath = "TestTeamProject"
$workitem.IterationPath = "TestTeamProject"
#Save work item
The only changes I made were to set the work item title using the IncidentTitle parameter, and to add the IncidentId and IncidentDescription parameters to the work item description field.
Click OK to close the script configuration window. Then click the Save button in the Authoring Tool to save all changes.
If I go out to Windows Explorer and look, I can see that multiple files are created. The two files I care about are the DLL and the XML file.
The DLL file contains the guts of the Windows Workflow that I just created. I need to copy that DLL to the root of my Service Manager Management Server (by default that is usually C:\Program Files\Microsoft System Center 2012 R2\Service Manager). That way, when the workflow defined in my XML management pack is triggered, SCSM can find the DLL containing the code.
After copying the DLL, I need to import the XML management pack. I can do this using the Service Manager console. Go to the Administrative workspace, and select Management Packs. Then click the Import task on the right hand side. Select the TFS.Integrations.xml management pack, and click the Import button. After importing the management pack, I want to make sure the management pack is “recognized” by Service Manager. I can do this by looking at the Operations Manager Event Log on the SCSM Management Server, and watching for an Event Id of 1201, followed by an Event Id of 1210.
Testing the Integration
With my new workflow in place, I now need to test it. To do so, I create a new Incident in Service Manager.
Once I save my incident, because I set the classification category to Software Problems, my workflow should be triggered. I can watch this by going to the Administrative workspace in the console, and selecting Workflows | Status. This shows me a list of all the workflows in Service Manager. I find the CreateTFSTaskFromNewSoftwareProblemsIncident workflow and select it. In the figure below, you can see that the workflow has run successfully twice, and that a third instance is currently scheduled.
If I click the refresh link, then I can see the scheduled instance of the workflow ran successfully.
And if I go out to Team Foundation server, I can see a new Task work item was created. The task work item has the same title as the Incident, and the Incident ID and Description are contained in the Task description.
Obviously there are enhancements that would need to be made to this process before it would be production ready. I should add some error handling to my script. And I need to add code into the workflow that would get the Task Id from TFS and store it back into the Incident in Service Manager. This would allow me to start bi-directional communication between both systems. In my next post, I’ll show how I can extend the Incident class in Service Manager to create a new field where I can store the Task Id, and I’ll modify my management pack to update the newly created field with the Task Id from Team Foundation Server.
To see the previous installments in this series, visit “100 Days of DevOps with PowerShell”.