One of the things that people often ask about is how to use the Service Manager SDK to:
-
create new objects,
-
update objects,
-
add relationships,
-
remove relationships
One of the keys to using the SDK in this way is to use type projections.
We have had a few blog posts on this in the past in introduce the concepts and examples:
Getting Started with Type Projections
More with Type Projections
Getting and Working with Type Projections – Basic
These blogs posts were a little abstract though.
This blog post shows you how to work with type projections using incident management as an example.
The Visual Studio project is attached for reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Packaging;
using Microsoft.EnterpriseManagement.ConnectorFramework;
namespace IncidentTypeProjection
{
class Program
{
static void Main(string[] args)
{
//First get a connection to the Management Group
EnterpriseManagementGroup emg = new EnterpriseManagementGroup("localhost");
//======================================================
//Example #1 - Creating a single incident object
//======================================================
Console.WriteLine("Creating an incident object....");
//Get the System.WorkItem.Incident class
ManagementPackClass classIncident =
emg.EntityTypes.GetClass(new Guid("A604B942-4C7B-2FB2-28DC-61DC6F465C68"));
//Also get the Medium urgency and impact enums
//since they are required values to create a new incident
//More information on working with enums here:
//http://blogs.technet.com/b/servicemanager/archive/2010/05/25/programmatically-working-with-enumerations.aspx
ManagementPackEnumeration enumUrgencyMedium =
emg.EntityTypes.GetEnumeration(new Guid("02625C30-08C6-4181-B2ED-222FA473280E"));
ManagementPackEnumeration enumImpactMedium =
emg.EntityTypes.GetEnumeration(new Guid("80CC222B-2653-2F68-8CEE-3A7DD3B723C1"));
//Now create a CreatableEnterpriseManagementObject so we can create a
//new incident object and populate its properties and Commit() it.
CreatableEnterpriseManagementObject cemoIncident =
new CreatableEnterpriseManagementObject(emg,classIncident);
//Just doing this for demo purposes. Obviously a GUID is not a good display name!
String strTestID = Guid.NewGuid().ToString();
//Set some property values
cemoIncident[classIncident, "DisplayName"].Value = strTestID;
cemoIncident[classIncident, "Title"].Value = strTestID;
cemoIncident[classIncident, "Urgency"].Value = enumUrgencyMedium;
cemoIncident[classIncident, "Impact"].Value = enumImpactMedium;
//And submit...
cemoIncident.Commit();
Console.WriteLine("Incident object created named: " + strTestID);
//======================================================
//Example #2 - Creating a Relationship between to Objects - Incidnet and User via the Affected User relationship
//======================================================
//Get the incident
Console.WriteLine("Creating an relationship between the incidena and a user....");
String strIncidentByTitleCriteria =
String.Format(@"<Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/"">" +
"<Expression>" +
"<SimpleExpression>" +
"<ValueExpressionLeft>" +
"<Property>$Target/Property[Type='System.WorkItem.Incident']/Title$</Property>" +
"</ValueExpressionLeft>" +
"<Operator>Equal</Operator>" +
"<ValueExpressionRight>" +
"<Value>" + strTestID + "</Value>" +
"</ValueExpressionRight>" +
"</SimpleExpression>" +
"</Expression>" +
"</Criteria>");
//System.WorkItem.Incident.Library MP
ManagementPack mpIncidentLibrary =
emg.ManagementPacks.GetManagementPack(new Guid("DD26C521-7C2D-58C0-0980-DAC2DACB0900"));
//Get the incident using the criteria from above...
EnterpriseManagementObjectCriteria emocIncidnetByTitle =
new EnterpriseManagementObjectCriteria((String)strIncidentByTitleCriteria,classIncident,mpIncidentLibrary,emg);
IObjectReader<EnterpriseManagementObject> readerEmoIncidentAffectedUsers =
emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(emocIncidnetByTitle,ObjectQueryOptions.Default);
EnterpriseManagementObject emoIncident = readerEmoIncidentAffectedUsers.ElementAt(0);
//Get a user..
//System.Domain.User class
ManagementPackClass classUser =
emg.EntityTypes.GetClass(new Guid("ECA3C52A-F273-5CDC-F165-3EB95A2B26CF"));
IObjectReader<EnterpriseManagementObject> readerEmoDomainUsers =
emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(classUser,ObjectQueryOptions.Default);
//Just getting whatever the first user is that comes back for demo purposes
EnterpriseManagementObject emoDomainUser = readerEmoDomainUsers.ElementAt(0);
//Create a Relationship between the service and the user
//System.WorkItemAfectedUser relationship type
ManagementPackRelationship relIncidentAffectedUser =
emg.EntityTypes.GetRelationshipClass(new Guid("DFF9BE66-38B0-B6D6-6144-A412A3EBD4CE"));
CreatableEnterpriseManagementRelationshipObject cemroIncidentAffectedUser =
new CreatableEnterpriseManagementRelationshipObject(emg, relIncidentAffectedUser);
//Set the source and target...
cemroIncidentAffectedUser.SetSource(emoIncident);
cemroIncidentAffectedUser.SetTarget(emoDomainUser);
//And submit...
cemroIncidentAffectedUser.Commit();
Console.WriteLine("Relationship created.");
//======================================================
//Example #3 - Creating relationships in bulk using Incremental Discovery Data
//======================================================
Console.WriteLine("Creating relationships to affected Windows computers...");
//First get the class and relationship type we want to work with
//Microsoft.Windows.Computer class
ManagementPackClass classWindowsComputer =
emg.EntityTypes.GetClass(new Guid("EA99500D-8D52-FC52-B5A5-10DCD1E9D2BD"));
//System.WorkItemAboutConfigItem relationship type
ManagementPackRelationship relAffectedConfigurationItem =
emg.EntityTypes.GetRelationshipClass(new Guid("B73A6094-C64C-B0FF-9706-1822DF5C2E82"));
//Now create a "bucket" (IncrementalDiscoveryData class) for putting
//updates into so we can submit them all at once.
IncrementalDiscoveryData iddRelationshipsToAdd = new IncrementalDiscoveryData();
//Get all the Windows computers in the system.
//This is not typical. Just doing this for demo purposes only.
IObjectReader<EnterpriseManagementObject> readerEmoWindowsComputers =
emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(classWindowsComputer,ObjectQueryOptions.Default);
foreach (EnterpriseManagementObject emoWindowsComputer in readerEmoWindowsComputers)
{
CreatableEnterpriseManagementRelationshipObject cemroAffectedConfigurationItem =
new CreatableEnterpriseManagementRelationshipObject(emg, relAffectedConfigurationItem);
//Set the source and target...
cemroAffectedConfigurationItem.SetSource(emoIncident);
cemroAffectedConfigurationItem.SetTarget(emoWindowsComputer);
//Add it to the bucket...
iddRelationshipsToAdd.Add(cemroAffectedConfigurationItem);
}
//And submit...
iddRelationshipsToAdd.Overwrite(emg);
Console.WriteLine("Relationships created.");
//======================================================
//Example #4 - Getting type projection objects and iterating through them
//======================================================
Console.WriteLine("Getting incidents and showing the users computers that are affected by them...");
//Getting incidents and then list the computers and users they are affecting
//System.WorkItem.Incident.ProjectionType
ManagementPackTypeProjection mptpIncident =
emg.EntityTypes.GetTypeProjection(new Guid("285CB0A2-F276-BCCB-563E-BB721DF7CDEC"));
ObjectProjectionCriteria opcIncident = new ObjectProjectionCriteria(mptpIncident);
IObjectProjectionReader<EnterpriseManagementObject> oprIncidents =
emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(opcIncident, ObjectQueryOptions.Default);
foreach (EnterpriseManagementObjectProjection emopIncident in oprIncidents)
{
if (emopIncident[relIncidentAffectedUser.Target].Count > 0)
{
//Show the affected user
Console.WriteLine(emopIncident.Object.DisplayName);
}
foreach (IComposableProjection icpAffectedConfigurationItem in emopIncident[relAffectedConfigurationItem.Target])
{
//Show each of the affected configuration items
Console.WriteLine("\t" + icpAffectedConfigurationItem.Object.DisplayName);
}
}
Console.WriteLine("Done showing incidents with related users and computers.");
//======================================================
//Example #5 - Creating objects and relationships at the same time via type projection
//======================================================
Console.WriteLine("Creating an incident and its relationships via a type projection...");
//First create the seed object
EnterpriseManagementObjectProjection emopIncidentToCreate = new EnterpriseManagementObjectProjection(emg, classIncident);
//Just using this for testing. Obviously using a GUID for a incidnet display name is not a good idea...
String strIncidentName = Guid.NewGuid().ToString();
//Set some properties on the object
emopIncidentToCreate.Object[classIncident, "DisplayName"].Value = strIncidentName;
emopIncidentToCreate.Object[classIncident, "Title"].Value = strIncidentName;
emopIncidentToCreate.Object[classIncident, "Impact"].Value = enumImpactMedium;
emopIncidentToCreate.Object[classIncident, "Urgency"].Value = enumUrgencyMedium;
//Then relate it to other objects as needed
IObjectReader<EnterpriseManagementObject> readerUsers =
emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(classUser, ObjectQueryOptions.Default);
foreach (EnterpriseManagementObject emoUser in readerUsers )
{
emopIncidentToCreate.Add(emoUser,relAffectedConfigurationItem.Target);
}
//And submit...
emopIncidentToCreate.Overwrite();
Console.WriteLine("Incident and relationships created...");
//======================================================
//Example #6 - Updating objects and relationships at the same time via type projection
//======================================================
Console.WriteLine("Updating an incident and its relationships at the same time via a type projection...");
//First get the EnterpriseManagmentObjectProjection
IObjectProjectionReader<EnterpriseManagementObject> oprIncidentsToUpdate =
emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(opcIncident, ObjectQueryOptions.Default);
foreach (EnterpriseManagementObjectProjection emopIncident in oprIncidentsToUpdate)
{
//Update a property
emopIncident.Object[classIncident, "DisplayName"].Value =
emopIncident.Object[classIncident, "DisplayName"].Value + " - Updated";
//Remove a relationship
foreach (IComposableProjection icpAffectedUser in emopIncident[relIncidentAffectedUser.Target])
{
icpAffectedUser.Remove();
}
//Add a relationship
//Just getting the first user here as an example
EnterpriseManagementObject emoUserToAdd =
emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(classUser,ObjectQueryOptions.Default).ElementAt(0);
emopIncident.Add(emoUserToAdd, relIncidentAffectedUser.Target);
}
}
}
}