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... Visual Studio Project 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); } } } }
Visual Studio Project
Hi Travis,
I want to retrieve the value of all the properties that are associated with class.As of now, in the EnterpriseManagementObject, I am only able to get the property name and not their value.
So is there a way to get the values for property ???
@Chirag -
Of course! :)
emopIncident.Object[classIncident, "DisplayName"].Value
After I Create the object and the relationship can I tell the Console to open the form for the newly created object so that the end user can add data.
@Nick - Are you running your code from inside of the console process or outside of it?