There are some relationship types in the system which have properties defined on them just like classes do. In fact, way deep down in the covers of the system, relationship types are really just special kinds of classes. Probably, the most prominent example is the System.DeviceHasSoftwareItem relationship type. It is the relationship type that keeps track of what software is installed on a given device (typically a computer but it can be other types of devices that derive from System.Device). For example, a relationship might be created between JoesComputer and the software item that represents Microsoft Office 2025 Professional. If this relationship exists, then you know that particular software title is installed on that computer. What if you want to know some additional information about that particular installation on Joe’s computer such as the installation date, installation path, or product key which is unique for every installation of that software title on all the computers it is installed on? That's where relationship type property properties come in!
The System.DeviceHasSoftwareItem relationship type has these exact properties defined on it. Exploring the relationship type in SMLets (PowerShell) I can see this:
See how there are three properties defined on this relationship type: SerialNumber, InstalledPath, InstalledDate? They are declared exactly the same way you declare class properties except the <Property> elements are contained by the <RelationshipType> element instead of a <ClassType> element.
OK, now let’s look at how to set these property values using the SDK. Here’s a quick code sample to show you how to do it:
That’s it! As you can see it is very similar to how you would set the properties on a regular object.
This is what it looks like in the console:
If you need to update a relationship object property, you just need to get the relationship object and set the properties using the format RelationshipObject[RelationshipType,”PropertyName”].Value = X format that you use for updating the properties of objects.
Further reading on working with relationships using the SDK can be found here:
Here’s the code in case you want to be able to copy it:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
namespace RelationshipData2
{
class Program
{
static void Main(string[] args)
{
EnterpriseManagementGroup emg = new EnterpriseManagementGroup("localhost");
ManagementPackRelationship mprComputerHasSoftwareInstalled = emg.EntityTypes.GetRelationshipClass(new Guid("224b24a8-83ac-d6e8-9d66-e1d6d4ebeeab")); //"System.DeviceHasSoftwareItemInstalled"
ManagementPackClass mpcWindowsComputer = emg.EntityTypes.GetClass(new Guid("ea99500d-8d52-fc52-b5a5-10dcd1e9d2bd")); //Microsoft.Windows.Computer
ManagementPackClass mpcSoftwareItem = emg.EntityTypes.GetClass(new Guid("e88c746c-27ba-5b70-9f78-13e96ad9cffb")); //System.SoftwareItem
IObjectReader<EnterpriseManagementObject> rdrComputers = emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(mpcWindowsComputer, ObjectQueryOptions.Default);
IObjectReader<EnterpriseManagementObject> rdrSoftware = emg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(mpcSoftwareItem, ObjectQueryOptions.Default);
//Create a new creatable relationship object of the relationship type that you want
CreatableEnterpriseManagementRelationshipObject cemroComputerHasSoftwareInstalled = new CreatableEnterpriseManagementRelationshipObject(emg, mprComputerHasSoftwareInstalled);
//Set the properties of the relationship object just like you do for regular objects
cemroComputerHasSoftwareInstalled[mprComputerHasSoftwareInstalled, "SerialNumber"].Value = "A-1-A-2";
cemroComputerHasSoftwareInstalled[mprComputerHasSoftwareInstalled, "InstalledPath"].Value = "C:\\Blah";
cemroComputerHasSoftwareInstalled[mprComputerHasSoftwareInstalled, "InstalledDate"].Value = DateTime.Now;
//Set the target and source objects as normal. Here I am just indiscriminantly using the first software and computer objects that come back from the DB in the reader queries above
cemroComputerHasSoftwareInstalled.SetTarget(rdrSoftware.FirstOrDefault<EnterpriseManagementObject>());
cemroComputerHasSoftwareInstalled.SetSource(rdrComputers.FirstOrDefault<EnterpriseManagementObject>());
//...And send it to the DB!
cemroComputerHasSoftwareInstalled.Commit();
//Just put this in here so I could see which computer had the software item added to it so I could look at it in the console
Console.WriteLine(rdrComputers.FirstOrDefault<EnterpriseManagementObject>()[mpcWindowsComputer, "DisplayName"].Value);
Console.ReadLine();
/* CODE TO CREATE A SAMPLE SOFTWARE ITEM
CreatableEnterpriseManagementObject cemoSoftwareItem = new CreatableEnterpriseManagementObject(emg, mpcSoftwareItem);
cemoSoftwareItem[mpcSoftwareItem, "Publisher"].Value = "Microsoft";
cemoSoftwareItem[mpcSoftwareItem, "VersionString"].Value = "1.0.0.0";
cemoSoftwareItem[mpcSoftwareItem, "ProductName"].Value = "Bob";
cemoSoftwareItem[mpcSoftwareItem, "LocaleID"].Value = "123";
cemoSoftwareItem[mpcSoftwareItem, "IsVirtualApplication"].Value = false;
//cemoSoftwareItem.Commit();
*/
}
}
}