Using the SDK to Create and Edit Objects and Relationships Using Type Projections
Published Feb 15 2019 04:07 AM 754 Views
First published on TECHNET on Oct 04, 2010
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-enumerati...
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);
}
}
}
}
Version history
Last update:
‎Mar 11 2019 08:34 AM
Updated by: