Update Resource Activity Example

The Update Resource Activity Class (Microsoft.ResourceManagement.Workflow. Activities.UpdateResourceActivity) is used within custom FIM workflows to update attributes on objects in the FIM Service database. To function, it requires a target object ID and an UpdateRequestParameter set, which contains the attributes that you want to update and the new values you wish to set them to.

In this example, I’m going to show you a very basic example of how to use the Update Resource Activity. This custom workflow will read the current request, then read the user object to pull out a few attributes, then update that user object based on the attributes I’ve read.

This very simple example could be replaced with a workflow using the Function Evaluator, but should hopefully detail how to use the update activity simply enough that you can figure out how to use it for more complicated tasks.

Step 1: Add a new Activity to your FIM Custom Activity Library

Step 2: Give that activity an appropriate name

Step 3: Add the relevant activities into the workflow In this example, we have added the Current Request Activity, a Read Resource Activity, an Update Resource Activity and two code activities

Step 4: Give the activities meaningful names.

Step 5: Double click each of the code blocks to promote the bindable properties for the code blocks.

Step 6: Add the Microsoft.ResourceManagement references to your activity.

Step 7: Write the code to initialise the Read Resource Activity to pull out the FirstName and LastName attributes for the current user. Note that we use the CurrentRequest acitvity to determine which user is the current user, but we could also omit this activity and use SequentialWorkflow.TryGetContainingWorkflow(this, out containingWorkflow) to get the current containing workflow and the target ID directly from that.

Step 8: Initialise the Update Resource Activity to update the user’s DisplayName and AccountName attributes using generated values. First, retrieve the FirstName and LastName values from the resource returned by the Read Resource Activity.

Step 9: Now, add the necessary properties and update parameters to update this object. Note that we first create a List (so remember to include System.Collections.Generic) of UpdateRequestParameter objects, add to that list, then convert it back into an array of UpdateRequestParameter objects as we assign it to the UpdateParameters property of the Update Resource Activity object.

Note that UpdateMode has three different members you can pass, according to the MS Documentation:

Insert Adds a new value to a multi-valued attribute.
Modify Modifies a single-valued attribute.
Remove Removes a value from a multi-valued attribute.

In this case, I am using Insert because I’m assuming that the attributes currently don’t have data in them – this still seems to work fine for single-value attributes. You may use modify if your attributes are likely to already have a value. For multi-value attributes (which I will go into more detail in a future example), you would add values like this:

Step 10: That’s the end of the workflow… now just make a GUI for it. Add a new class to your project

Step 11: Add the Microsoft.ReosurceManagement includes, an include to your activity (if it’s in a different namespace – if you’ve separated your project into Activity/WebUI folders as per the MS documentation, then it most likely will be) and then make the class implement the ActivitySettingsPart class.

Step 12: Right click on ActivitySettingsPart and select “Implement Abstract Class” to generate the member methods which you must fill out.

Once that’s been done, fill out the form as follows.

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using Microsoft.ResourceManagement.Workflow.Activities;
 using Microsoft.IdentityManagement.WebUI.Controls;
 using FIMSpecialist.DemoLibrary.Activities;

 namespace FIMSpecialist.DemoLibrary
 {
     public class UpdateResourceExampleUI : ActivitySettingsPart
     {
         public override System.Workflow.ComponentModel.Activity GenerateActivityOnWorkflow(SequentialWorkflow workflow)
         {
             if (!this.ValidateInputs())
             {
                 return null;
             }

UpdateResourceExample updateResource = new UpdateResourceExample();
             return updateResource;
         }

public override void LoadActivitySettings(System.Workflow.ComponentModel.Activity activity)
         {
             UpdateResourceExample updateResource = activity as UpdateResourceExample;

if (null != updateResource)
             {
             }
         }

public override ActivitySettingsPartData PersistSettings()
         {
             ActivitySettingsPartData data = new ActivitySettingsPartData();
             return data;
         }

public override void RestoreSettings(ActivitySettingsPartData data)
         {
             if (null != data)
             {
             }
         }

public override void SwitchMode(ActivitySettingsPartMode mode)
         {
             bool readOnly = mode == ActivitySettingsPartMode.View;
         }

public override string Title
         {
             // This is the title that we see when we are adding the activity to a workflow
             get { return "Update Resource Activity Example "; }
         }

public override bool ValidateInputs()
         {
             return true;
         }
     }
 }

Note that for this example we’re really not doing much on the Web UI. A future tutorial will have further detail on enhancing the UI aspect of the to pull additional parameters, etc.

Step 13: Install the Workflow into FIM, and add the Activity Information Configuration item under Administration / All Resources in the FIM Portal. A future tutorial will detail how to do this. Your activity is now ready to be included in workflows.

Final code for the UpdateResourceExample.cs file looks like this:

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
using Microsoft.ResourceManagement.Workflow.Activities;

namespace FIMSpecialist.DemoLibrary.Activities
{
    public partial class UpdateResourceExample : SequenceActivity
    {
        // This is the guid for the FIM Service built-in admin account.
        // We will use it to execute each of our workflow activities.
        const string FIMAdminGuid = "7fb2b853-24f0-4498-9534-4e10589723c4";

        public UpdateResourceExample()
        {
            InitializeComponent();
        }

        private void InitialiseReadUser_ExecuteCode(object sender, EventArgs e)
        {
            // Set the Actor ID for the Read Activity to the FIM Admin GUID
            ReadUser.ActorId = new Guid(FIMAdminGuid);
            
            // Set the Resource to retrieve as the currently requested object.
            // Note, you could also set this to the target ID of the containing workflow
            ReadUser.ResourceId = CurrentRequest.CurrentRequest.Target.GetGuid();

            // Set the selection parameters as the first name and last name
            ReadUser.SelectionAttributes = new string[] { "FirstName", "LastName" };
        }

        private void InitialiseUpdateUser_ExecuteCode(object sender, EventArgs e)
        {
            // Get the object that was read using the Read Activity Resource into a ResourceType object
            // In a real-world workflow, you would check that anything was returned at all.
            ResourceType user = ReadUser.Resource;

            // Get the first name and last name from this object.
            // again, in a real-world workflow, you should check that these values are not null.
            string firstname = (string)user["FirstName"];
            string lastName = (string)user["LastName"];

            // generate an account name and display name
            string accountName = firstname.Substring(0, 1) + lastName;
            string displayName = string.Format("{0} {1}", firstname, lastName);

            // Set the actor ID and the resource ID again.
            UpdateUser.ActorId = new Guid(FIMAdminGuid);
            UpdateUser.ResourceId = CurrentRequest.CurrentRequest.Target.GetGuid();

            // Create a list of UpdateRequestParameter objects
            List updateRequestParameters = new List();

            // Add the AccountName and DisplayName we generated as parmaters to update on the object
            updateRequestParameters.Add(new UpdateRequestParameter("AccountName", UpdateMode.Insert, accountName));
            updateRequestParameters.Add(new UpdateRequestParameter("DisplayName", UpdateMode.Insert, accountName));            
                        
            // Conver the update parameters list into an array of UpdateRequestParameter objects and assign it
            // to the UpdateParameters property of the Update Resource Activity
            UpdateUser.UpdateParameters = updateRequestParameters.ToArray();

        } // end of InitialiseUpdateUser_ExecuteCode
    }
}