Workflow - SMP - ASDK - Asset Ownership

Published on Friday, 9 October 2015

In this Article I'm going to explain how Asset Ownership is controlled in the smp SMP and how to maintain it using Workflow Workflow and the ASDK.

Let's look at it in the SMP first.

Home | Service and Asset Management | Manage Configuration Items

Let's find a Computer Computer

Folder (-) CI Management | Folder Computers and Peripherals | Computer Computer

Search for one and Right-Click | Edit () Edit

Scroll down to Asset Owners and "Click to select..." or click the EditEdit button

Edit - Computer - Asset Owners

This can either be a User or a Department.

Search for the User, select and click OK.

This is configured using a Resource Association.

There are two, one for User and one for Department.

Reports Folder Settings | Folder Notification Server | Folder Resource and Data Class Settings | Folder Resource Associations | Folder CMDB Association Types | Resource Association Asset User Owner

​GUID 'ed35a8d1-bf60-4771-9dde-092c146c485a'

Reports Folder Settings | Folder Notification Server | Folder Resource and Data Class Settings | Folder Resource Associations | Folder CMDB Association Types | Resource Association  Asset Department Owner

​GUID '1466e770-4413-4517-a89d-6599b8a7f144'

You can see who is associated to what with the following SQL:

SELECT * 
FROM ResourceAssociation ra
WHERE ra.ResourceAssociationTypeGuid = 'ed35a8d1-bf60-4771-9dde-092c146c485a'

So we need to create an Association, let's look to the SDK.

There's a "Create Resource Association​" we can use.

  • http://localhost/altiris/asdk.ns/ResourceManagementService.asmx?op=CreateResourceAssociation

Inputs:

  • resourceAssociationTypeGuid
  • parentResourceGuid (Asset)
  • childResourceGuid (User)

Create a Int Web Service Generator (Video)

We can now call this in our Workflow WF.

Try this then check the SQL and the RA Table should reflect this but if you then check in the smp SMP the Asset Owners section won't, what's going on?

(Other Associations work just fine)

Let's do some investigation, I like to use both a SQL Profiler and the Altiris Profiler.

We have a call to 'spResourceAssociationsInsert', this makes sense.

EXECUTE spResourceAssociationsInsert 
   @ResourceAssociationTypeGuid=N'ed35a8d1-bf60-4771-9dde-092c146c485a', 
  @ParentResourceGuid=N'e4fc9fc1-a75a-4532-8a82-159d2477d0fa', 
  @ChildResourceGuid=N'f90f37c8-4562-48be-b8f3-3b0b4123086b', 
  @HistoryEnabled=1

But there is also another call to insert values into another Table (Inv_Ownership_Details).

INSERT INTO 
  dbo.[Inv_Ownership_Details] ([_ResourceGuid], [Owner], [Ownership Percentage]) 
VALUES 
  ('e4fc9fc1-a75a-4532-8a82-159d2477d0fa', 'f90f37c8-4562-48be-b8f3-3b0b4123086b', 100)

Now we could just create a SQL Generator but I don't like to use these for any ALTER commands.

There must be a better way.

Let's have another look at those Web Services:

Save Data Class from Resource Modellooks like it should work

  • http://localhost/altiris/nswebservice/resourcemodel.asmx?op=SaveDataClass

Add that to our previous Int Integration component and try it out in Workflow WF.

This just doesn't work, there is no way to pass in any dynamic data so this can't be a viable solution.

Toomas was a great help and got us some sample code from the Asset Team.

using System;
using Client.ProxyClass;

namespace client
{class Program{	static readonly Guid OwnershipDetailsDataclassGuid = new Guid("0cd0318b-ad51-4d38-8ea3-2612d12189de");	private const string UserId = "put here user name";	private const string Password = "put here user password";
	static void Main(string[] args)	{
		var comp = new Guid("927a7afe-ab4d-40d1-b11f-72111e6d540d"); //<-set up computer guid		var user = new Guid("e0b8a57b-9b2b-4f07-8b9e-d66a3d65d678"); //<-set up user guid
		var field0 = new DataClassFieldData { FieldName = "Owner", Value = user };		var field1 = new DataClassFieldData { FieldName = "Ownership Percentage", Value = 100.0 };		var row = new DataClassRowData { DataElements = new[] { field0, field1 } };		var dcd = new DataClassData		{			DataClassGUID = OwnershipDetailsDataclassGuid,			DataRows = new[] { row }		};
		var client = new ResourceModelService {Credentials = new System.Net.NetworkCredential(UserId, Password)};		client.SaveDataClass(comp, new[] { dcd });	}}
}

We tested this and got the Inv_Ownership_Details Table updating but how do we translate this into Workflow WF?

Maybe the Code (Script) Component Script Generator? Or why don't we build a Component?

Where do we start?

That's a lengthy process in itself so that can be discussed in a future Article.

Chris, a fellow Protirus C# Dev, got to work and created a Component we could use.

  • dll Protirus.AssetOwner.Service.dll

If you'd like a copy of this do get in touch info@protirus.com

One last thing we need to do in our Workflow is to check if there is already an Owner Association before creating one, we can use the Break Association Web Service from Resource Model.

  • http://localhost/altiris/nswebservice/resourcemodel.asmx?op=BreakAssociation

Now with a combination of the Break Association, Create Association and our new dll any Asset Ownership changes will now be reflected in the SMP.


Useful Documents

"<Install Drive>:\Program Files\Altiris\Altiris ASDK\Help\ASDK7.6.chm"


Web Services

  • Resource Model

    • http://localhost/altiris/nswebservice/resourcemodel.asmx
      • Break Association
        • http://localhost/altiris/nswebservice/resourcemodel.asmx?op=BreakAssociation
      • Remove Data Class From Resource
        • http://localhost/altiris/nswebservice/resourcemodel.asmx?op=RemoveDataClassFromResource
      • Save Data Class
        • http://localhost/altiris/nswebservice/resourcemodel.asmx?op=SaveDataClass
  • Resource Management Service

    • http://localhost/altiris/asdk.ns/ResourceManagementService.asmx​
      • Create Resource Association​
        • http://localhost/altiris/asdk.ns/ResourceManagementService.asmx?op=CreateResourceAssociation

Symantec Case Info

Case Number 08713954 ETrack ET3830607

Protirus.png