Blog Post

System Center Blog
5 MIN READ

Using the SDK to Create and Edit Objects and Relationships Using Type Projections

System-Center-Team's avatar
System-Center-Team
Former Employee
Feb 15, 2019
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-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);
}
}
}
}
Updated Mar 11, 2019
Version 4.0
No CommentsBe the first to comment