Sometimes, while trying to figure out FIM 2010 custom workflows, it seems to me that everyone else finds this stuff bleedingly obvious – but then I remind myself that actually, I’m not a complete idiot, and if I’m finding it all a bit like wading through chest-high treacle, with submerged barbed wire for added interest, then other people probably do too. So in case, like me, you couldn’t figure out how to use the ReadResourceActivity from the scantily provided documentation, here is what I have managed to figure out.
What is it for?
The ReadResourceActivity is used to look up an object in the FIM Portal database and return it to your workflow. You feed it a FIM GUID through the ResourceId property and it returns you a copy of the resource’s attributes in the Resource property.
In the pictures in this post you’ll see the word “Powershell” cropping up. In fact I’m working on an activity to run powershell cmdlets and scripts and I’ve arrived at the point where I’d like to include Target and Requestor properties in cmdlet arguments. Perhaps something like this:
Add-MailboxPermission -Identity [//Target/AccountName] -User [//Requestor/AccountName] -Accessright Fullaccess
Anyway, that’s the idea, and I’ll let you know if I get there.
Adding a ReadResourceActivity
|Before dragging in the ReadResourceActvity, this Workflow had only a CurrentRequestActivity and a code activity, very much like the LoggingActivity example (which I recently translated into VB.NET).
I plan to use this activity to read properties about the Target of this workflow – that is, the object in FIM which is in the process of being added or modified. Later I will also add another ReadResourceActivity to get the properties of the Requestor.
In this picture, all I’ve done to the ReadResourceActivity so far is to give it a name. The other properties are the initial defaults. You can actually compile and run your activity at this point, but you’ll get a PostProcessingError in FIM.
|The next thing you need to do is create DependencyProperties to bind to the parameters. These are something like global variables that you can use in your code, either by writing a value in, or reading a value out.
The simplest thing to do here is click on the link which says Promote Bindable Properties. This will create the DependencyProperty code for you (which you should not need to touch) and will add the bindings.
The one point to note here is that you lose the ability to set the list of SearchAttributes directly in this interface. If you don’t click Promote Bindable Properties then, when you click on the elipses next to SelectionAttributes, instead of the usual dialog allowing you to select or create a DependencyProperty, you get a box where you can enter the list of attributes you want returned as part of the resource loookup. In my case however I want to dynamically change the list of SelectionAttributes based on what’s been entered in the FIM Workflow, so I prefer to go with the bound property, as pictured here.
Set Initial Values
|I regret to say that this bit took me ABOLUTELY AGES to figure out. Before you can use the ReadResourceActivity you have to set the “input” properties:
The way I am doing this is by creating a code activity before the ReadResourceActivity. I’ll set the input properties here, the ReadResourceActivity will run, and then I’ll be able to use the resulting Resource parameter in my code that follows.
All I’ve done here is to drag in the Code activity and give it a name. When I double-click it the code block is automatically created and that red exclamation mark goes away. I then fill the Sub in as shown below. Note I could also set “Me.ReadTarget_ActorId1” to “containingWorkflow.ActorId” which would make the ReadResourceActivity run with the rights of the workflow requestor, but I thought it interesting to show how you can use a different account for some steps.
Private Sub InitializeReadResourceActivity_ExecuteCode(ByVal sender As System.Object, ByVal e As System.EventArgs) '' Set the ActorID to the Built-In Administrator account Me.ReadTarget_ActorId1 = New Guid("7fb2b853-24f0-4498-9534-4e10589723c4") '' Find the TargetID and use it to set the ResourceID on the ReadTarget actvity Dim containingWorkflow As SequentialWorkflow = Nothing If Not SequentialWorkflow.TryGetContainingWorkflow(Me, containingWorkflow) Then Throw New InvalidOperationException("Could not get parent workflow!") End If Me.ReadTarget_ResourceId1 = containingWorkflow.TargetId '' Set the list of Search Attributes based on your own requirements Dim targetSearchAttribs As String() = Nothing ' Add values to the targetSearchAttribs array as required Me.ReadTarget_SelectionAttributes1 = targetSearchAttribs End Sub
Using the Resource
|In any code block following the ReadResourceActivity you can use the retrieved object via the Resource property – in this case, Me.ReadTarget _Resource1.
To access a particular attribute value just put it’s name in brackets as shown. Obviously, I had to include AccountName in the array Me.ReadTarget_SelectionAttributes1 when I initialized it.
Actually I’m not going to list all the errors I saw here because they were many and varied and mostly due to my complete lack of understanding about how to use this activity. Hopefully, having walked you through it here, you won’ have the same problems!
I will mention however that the “UnwillingToPerform” error I saw a few times was connected to not setting the ActorId.