Given the very poor mass of examples found for FIM 2010, I’ll be aiding this problem for people new to FIM 2010. Manipulation of data in FIM is done in a number of different ways. One developer centric way is via execution of a custom workflow (.NET 3.5), which will be the method I’ll be exploring in this sample.
For an overall introduction to FIM 2010 – see this post:
http://blog.clauskonrad.net/2011/05/fim-2010-developers-quick-introduction.html
The process goes through these steps:
1) Create the custom workflow in Visual Studio (2008/2010)
2) Install it into FIM 2010
3) Create a condition for invoking the workflow (via an MPR)
4) Invoke the workflow

The above figure (coming from Microsoft's website) presents the extension points in FIM 2010. As seen the FIM Service exposes 3 different kinds of workflows for you to extend:
6) Authentication (who is calling)
7) Authorization (is the individual allowed access/execution)
8) Action (basically every other manipulation)
The nature of these workflow types is kind of self-explanatory and the “Hello World” sample will be an Action Workflow. But, before engaging in code, let’s determine what actually happens when triggering an event in the FIM Service.
Every incoming action in a FIM Service is presented to the FIM Service via it’s web-service API as a Request. The Request contains info on What Operation (Create,Update,Read,Delete) is requested, Who (Actor) is calling and for What Resource (e.g. PersonObject) is the request intended? The below illustration (coming from Microsoft) shows the request processing of an incoming Request.
.gif)
Note: The webservice (as far as I know) in itself does not perform any action apart from presenting the Request to the FIM Service for evaluation.
As seen in the figure – the last step is calling of an ‘Action’ workflow if such exists. This is where we will be coming in. Before invoking the Action Workflow lets see how the workflows are actually hosted in FIM?
Workflows in FIM 2010
Coming from a WF 3.5 background, you should think that it is straight forward? Well – not entirely :-). The workflows need to obey to certain rules and to be embedded as an activity in a special parent sequential workflow class (Microsoft.ResourceManagement.Workflow.Activities.SequentialWorkflow) from FIM’s universe. This FIM parent workflow actually itself inherits from a System.Workflow.Activities.SequentialWorkflowActivity-class from the native WF 3.5 namespace.

Why a need for this special FIM workflow?
The FIM version of the SequentialWorkflow holds a number of FIM related properties that allows you to gain access to among other things, the incoming Request object as well as the Resource you wish to manipulate (e.g. PersonObject). If you inherited directly from the std. WF version, you would not be able to gain access to these in a FIM context essential properties! If you open the FIM version (the blue element above) in e.g. Reflector or Visual Studio; you will see properties of type ResourceID, Resource, Request etc.
Okay – so far so good; now we know how it is hosted. So how do you create a HelloWorld workflow?
Creating your HelloWorld workflow
1) Open Visual Studio and select Target = 3.5
2) Select ProjectType = ‘Workflow Activity Library’

3) By default – this projecttype will present you with an Activity that inherits from System.Workflow.Activities.SequenceActivity, which is exactly what you need to create a sequence of actions.

4) To read a request – drag a ReadResourceActivity into the design surface

5) Bind Actor, Resource and ResourceID of this activity to 3 new fields

6) Override the Execute method' and retrieve the Parent workflow (the FIM version)
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
SequentialWorkflow parentWF = null;
if (!SequentialWorkflow.TryGetContainingWorkflow(this, out parentWF))
throw new InvalidOperationException("Logging activity can not run outside the context of the FIM SequentialWorkflow.");
readRequest_ResourceId = parentWF.RequestId;
readRequest_ActorId = parentWF.ActorId;
m_logData.Add("Got called by FIM...");
m_logData.Add("\tIncoming requestId: {0}", readRequest_ResourceId);
m_logData.Add("\tIncoming actor: {0}", readRequest_ActorId);
base.OnSequenceComplete(executionContext);
return base.Execute(executionContext);
}
The parent workflow is the special FIM-version, remember? This guy carries the incoming Request, Actor and Resource to be manipulated. Set the newly created fields ‘ResourceID’ and ‘Actor’ to point to these properties of the ParentWF (i.e. let the parentWF populate the fields of your custom activity). Note that if we fail to retrieve the parentworkflow, we will throw an exception. It makes little sense to run without it!
7) Override the OnSequenceComplete method to report on progress
protected override void OnSequenceComplete(ActivityExecutionContext executionContext)
{
var reqType = readRequest_Resource as RequestType;
if (reqType == null)
throw new InvalidOperationException("Cannot locate current request...");
m_logData.Add("Request (type=[{0}]) has been processed with the following parameters:", reqType);
var reqParameters = reqType.ParseParameters<CreateRequestParameter>();
foreach (var item in reqParameters)
{
m_logData.Add("\trequestParameter.PropertyName: [{0}] / requestParameter.Value: [{1}]", item.PropertyName, item.Value);
}
base.OnSequenceComplete(executionContext);
}
Note: Due to some reason unknown to me at this time, the ‘Resource’ itself is only available at the time the OnSequenceComplete method is being called by the Parent Workflow. Due to this reason, it is extracted in the OnSequenceComplete method and NOT the Execute method (where Resource = null).
That was a long way to go, but we are not done yet.
Installing the workflow in FIM 2010
To install the workflow (the parent FIM version) including your own SequenceActivity, you need to write some XOML to import into FIM. The XOML is generated quite easily in a console app with these lines of code:
static void Main(string[] args)
{
var logAct = new FIMLoggingActivity();
var seqWorkflow = new SequentialWorkflow(); //parent = special FIM SeqWF!
seqWorkflow.Activities.Add(logAct); //add std. WF acticity to parent
var settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
using (var xmlWriter = XmlWriter.Create("CustomWF.xoml", settings))
{
var ser = new WorkflowMarkupSerializer();
ser.Serialize(xmlWriter, seqWorkflow);
xmlWriter.Flush();
}
}
As seen, these few lines of code will create a FIM SequentialWorkflow as parent and add your custom activity (‘logAct’ in the above) as the single activity. Next, it will simply serialize the objectgraph to disk using the standard XmlWriter (system.xml). This resulting file (“customWF.xoml) will be imported into FIM when creating the workflow.
1) Copy the assembly from your development machine –> FIM Server at (C:\Program Files\Microsoft Forefront Identity Manager\2010\Service\*.*)
2) Open the FIM Portal and hit ‘administration’ – ‘workflows’
3) Press ‘new’ and import the xoml-file

4) You are done importing the WF into FIM
Invoking the workflow in FIM 2010
Finally – you need some means of invoking the new workflow.
1) Open ‘Management Policy Rules’
2) Add a new policy

3) Note that is will run when a single property is edited on a Person object (All People)
4) Select Target Resources (before/after)
5) Select your ‘Action’ workflow (in the below ‘CK_MobileWF’)

6) You are done!
Now – open a person object and change a property. This will trigger the MPR which will trigger your workflow (technically the parentWF which will call your activity).

That’s how ‘easy’ it is (in the simple version!)
StackOverflow Tags:
FIM 2010,
.NET