Custom Activity read reference Attribute
Hi Fimster
I develop a custom workflow Activity to execute PowershellScripts.
Within a Workflow i store the Data of a Person Resource (Reference Attribute) with a Function Evaluator.
Target [//WorkflowData/CustomRef]
Then my Custom Powershell Activity becomes active.
Now my Problem. How ca i read the CustomRef within the Workflowdata or if that is not possible how can i read the Reference directly of the Person resources?
I know that a single Attribute from Type String can be read with a readResourceActivity
user["AccountName"].ToString()
The Containing Workflowdata can be accessed with
String workflowDataValue = containingWorkflow.WorkflowDictionary["AccountName"].ToString()
I hope someone can Help me.
Kind Regards V. H.
May 4th, 2011 5:52am
Hi!
If you store a reference value to the Workflow Dictionary you can bring it out the same way you do with AcccountName and what you get is a Guid as a string. Sometimes this Guid could be prefixed with something like "UUID:" if I remember correct and that
could easily be trimmed of and then you can create a new Guid from it using....
Guid refValue = new Guid(<your string here>);
Another way to extract both [//Target/... and [//WorkflowData/... values is to use the resolveGrammarActivity...
There are already two Powershell activities available:
http://www.wapshere.com/missmiis/powershell-activity
http://fimpowershellwf.codeplex.com/ (this one I'm currently working on to add a lot of new functionality)
//HenrikHenrik Nilsson, ILM/FIM MVP Blog: http://www.idmcrisis.com Company: Cortego (http://www.cortego.se)
Free Windows Admin Tool Kit Click here and download it now
May 4th, 2011 6:26am
Hi Henrik
This works only for a single Reference. If i have a reference like Members from the Group Resource ( Attribute is Multi-valued) it dont work. Do you have a hint for me?
Greets
May 4th, 2011 8:20am
I see, it's a multivalue reference you're after... Well I'm not sure but the containingWorkflow.WorkflowDictionary["YourMultivalueReference"] will return a value of the object datatype and you have to try to find out what underlying datatype keeps your multivalue
reference, my guess is that is likely to be a Guid array (Guid[]) or something like that and instead of extracting it using the ToString() method you have to extract it according to the datatype like maybe...
var yourMultivalueRef = containingWorkflow.WorkflowDictionary["YourMultivalueReference"] as Guid[];
Tip: Hook the VS debugger to find out...
//Henrik
Henrik Nilsson, ILM/FIM MVP Blog: http://www.idmcrisis.com Company: Cortego (http://www.cortego.se)
Free Windows Admin Tool Kit Click here and download it now
May 4th, 2011 9:50am
Okay The datatype is a List<UniqueIdentifier>
But it doesnt work if cast it this way.
List < UniqueIdentifier > listref = new List<UniqueIdentifier>()
listref= containingWorkflow.WorkflowDictionary["YourMultivalueReference"] as List<UniqueIdentifier>
I dont know whats goining wrong.
Regards.
May 4th, 2011 11:41am
I'm afraid it isn't possible passing multivalued attributes to WorkflowData using the FunctionEvaluator activity, I get this error and I recommend you to check out your eventlog as well.
FunctionLibrary: System.ArgumentException: The parameter for the function is of an unknown type: '7fb2b853-24f0-4498-9534-4e10589723c4 ;bd410072-eb95-4b0e-a4dd-e6541bf858a2'. System.FormatException: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
at System.Guid..ctor(String g)
at Microsoft.MetadirectoryServices.FunctionLibrary.AttributeFlowMappingHandler.RetrieveSingleArgument(CSEntry csentry, MVEntry mventry, Boolean isInbound, XmlNode argNode, WorkflowParameterContext wfContext)
at Microsoft.MetadirectoryServices.FunctionLibrary.AttributeFlowMappingHandler.RetrieveSingleArgument(CSEntry csentry, MVEntry mventry, Boolean isInbound, XmlNode argNode, WorkflowParameterContext wfContext)
at Microsoft.MetadirectoryServices.FunctionLibrary.AttributeFlowMappingHandler.EvaluateExpression(CSEntry csentry, MVEntry mventry, XmlNode functionNode, Boolean isInbound, WorkflowParameterContext wfContext)
at Microsoft.ResourceManagement.Workflow.Hosting.ResolverEvaluationServiceImpl.EvaluateFunction(String functionExpression)
A workaround could be either to use the ResolveGrammarActivity to resolve the [//WorkflowData/VariableName] or why not the [//Target/AttributeName] directly from within your custom activity. Another option could be to use the ReadResourceActivity and get
the value directly from the Resource.
//Henrik
Henrik Nilsson, ILM/FIM MVP Blog: http://www.idmcrisis.com Company: Cortego (http://www.cortego.se)
Free Windows Admin Tool Kit Click here and download it now
May 4th, 2011 2:10pm
What are you trying to do exactly? So what is the powershell you want to run and what is the multivalued attribute?http://www.wapshere.com/missmiis
May 4th, 2011 2:54pm
Great Henrik. Thank you. Now i read directly from the User ResourceType. I've got the UniqueIdentifier List. now i must look how can i convert it to real Names ;-)
Other Question! Is there a Custom FunctionEvaluator avaible to store Multivalue Attribute to Workflowdata?Maybe Tools4FIM?
Free Windows Admin Tool Kit Click here and download it now
May 5th, 2011 4:06am
Hi Carol
I store the FullMailboxPermission in a Reference Attribute (Multivalued) on the User Resource. With the Powershell i want to set the correct Permission on the Object in Exchange and AD. (Send-as)
:-)
Greets
May 5th, 2011 4:08am
Mailbox permissions are better done with a dedicated object type - then you only ever need handle single-valued attributes. See my post on the subject:
http://www.wapshere.com/missmiis/why-create-a-delegation-resource-type-in-the-fim-portalhttp://www.wapshere.com/missmiis
Free Windows Admin Tool Kit Click here and download it now
May 5th, 2011 5:16am
i know your solution. But how can i flow it from a dedicated HR System. There is also a reference Attribute available witch stores the User/Group that should have Access to the Mailbox.
I think it's easies todo like my way Or not?
May 5th, 2011 5:37am
How can i loop throuth my UniqeIdenfifier and get the AccountName.I know i can use the ResolveGrammar or ReadResource Activity but how can i use it in a While loop or Foreach?
Any proposals?
Free Windows Admin Tool Kit Click here and download it now
May 5th, 2011 5:56am
You can use a while look in a custom workflow activity - I did one in this example:
http://www.wapshere.com/missmiis/generate-unique-attribute-activity
If you were to create delagation objects from HR data you'd need to put something between the HR data source and FIM Sync that presents the data in the way you want. I do this all the time - normally with SQL and SSIS.http://www.wapshere.com/missmiis
May 5th, 2011 7:23am
I agree with Carol that maybe you should have taken another approach from the beginning and my recommendation is to use the EnumerateResourcesActivity that you feed with an XPath query and a list of the attributes you wish to get.
http://www.idmcrisis.com/post/2009/11/16/enumerateresourcesactivity-the-follow-up.aspx
http://social.technet.microsoft.com/Forums/en-US/ilm2/thread/9551bd05-333c-4f43-a967-3d7642ed4f38/#3e8e6b4b-1fa0-4531-9112-2aff9b962e11
//Henrik
Henrik Nilsson, ILM/FIM MVP Blog: http://www.idmcrisis.com Company: Cortego (http://www.cortego.se)
Free Windows Admin Tool Kit Click here and download it now
May 5th, 2011 7:35am
Hi Carol & Henrik
Okay i understand your approach. I think at the moment it's easier to be done for me like may way. In the While Activity i put my CodeActivity1 and ReadResourceActivity and antother CodeActivity2. The While Condition is set to "Declarative Rule Condition"
(this.loopAgain == True)
If i debug my Activity the Workflow ends with a exception
System.Workflow.Activities: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Workflow.Activities.Rules.RuleConditionReference.InitializeProperties()
at
I knowits the "Declarative Rule Condition" but i dont now why. My loopAgain is set to true and i set it only to false if there are no elements in my List Objects.
How do you set your "Declarative Rule Condition"in your Example Carol?
Greets
May 10th, 2011 6:52am
With a Custom Code Contition it Works. Now the next problem. Damn.....
ReadresourceActivity dont work inside the While
I set the ResourceId and ActoriD
this.readResourceActivity1.ActorId = containingWorkflow.ActorId;
this.readResourceActivity1.ResourceId = listguid[loopcount].GetGuid();
Then in another Codeactivity i try to read the AccountName
ResourceType user = readResourceActivity1.Resource;
if (user != null)
{
object val = user["AccountName"];
}
The Workflow ends with an exception.
Invalid requestor specified for Get Operation. .........................
greets
Free Windows Admin Tool Kit Click here and download it now
May 10th, 2011 8:55am
I'm using an Enumerate activity inside a while loop - I don't see why Read should be any different. You know you have to put a Sequential Actoivity block inside the while loop so you can add multiple steps?
I'm going to post the entire new version of that activity shortly. I'll post it as a VS project this time which should make it easier to follow.http://www.wapshere.com/missmiis
May 10th, 2011 9:29am
If you ever have an activity that works normally but then exhibits weird behavior in a loop, it's generally always a problem with activityexecutioncontexts.
Loop constructs in windows workflow are wonky. They don't loop like regular code; instead, you can think of it as it makes a copy of the block of code (your activity) and runs it.
That means things that you reference inside the loop may not work correctly. (for example, I don't know how you're updating loopcount and where it's stored. If it's created inside the activity that's inside a loop...that's a good area to debug for
problems. Try storing all that stuff out & using activityexecutioncontext).
The enumerate activity does all that for you (I'm sure people will attest how annoying it was to use the enumerate activity during beta).
Imo, it's insanely stupid how complicated this is but that's the way it's done in Windows workflow 3. For a better explanation, check out: http://blogs.msdn.com/b/advancedworkflow/archive/2006/03/21/557121.aspxex-MSFT developer, now FIM/MIIS/ILM/WPF/Silverlight consultant | http://blog.aesthetixsoftware.com/
Free Windows Admin Tool Kit Click here and download it now
May 10th, 2011 9:53am
Yes i Know. I put a SeqAcivity Inside the While. Strange Issue. Now i try it with a EnumerteResourceActivity. Hope that works.
May 10th, 2011 9:59am
Hi Ikrima
If i donit use a ReadResourceActivity inside the While and put the Guids of my List to the Eventlog All Items Proccesses the right way. Only if a use a readResActivity the WF Fails. Very Strange.
Free Windows Admin Tool Kit Click here and download it now
May 10th, 2011 10:17am
The reason your workflow fails is probably because your trying to read information from the template ReadResourceActivity within the While activity. An important aspect of Workflow Foundation is that no activity instance is allowed to execute more than once
therefore all iteration activities like the While and Replicator activities instantiates a new instance of child activites for each loop whereas the activity put within the While activity from the GUI is only used as a template and never actually executed.
Also you should know that you could use the EnumerateResourcesActivity instead of a ReadResourceActivity within a While activity since it's an iterating activity as well and just like the While activity iterates all resources found using the XPath expression
supplied and will return the attribute values you specify in the Selection attribute. The problem with the EnumerateResourcesActivity is that it have the wrong designer attached that doesn't allow you to add child activities in the WF GUI, instead you must
add child activities using code.
I've blogged about the EnumerateResourcesActivity here...
http://idmcrisis.com/?tag=/enumerate
Also, check out the FIM Service MSDN Reference for the EnumerateResourcesActivity here...
http://msdn.microsoft.com/en-us/library/microsoft.resourcemanagement.workflow.activities.enumerateresourcesactivity.aspx
//Henrik
Henrik Nilsson, ILM/FIM MVP Blog: http://www.idmcrisis.com Company: Cortego (http://www.cortego.se)
May 11th, 2011 2:41am
Yeah now it works ;-) Great.
Thats the Solutution.
SequenceActivity currentParentSequenceActivity = (SequenceActivity)((CodeActivity)sender).Parent;
ReadResourceActivity currentread = currentParentSequenceActivity.Activities.OfType<ReadResourceActivity>().First();
currentread.ActorId = new Guid("7fb2b853-24f0-4498-9534-4e10589723c4");
:-) Same as it here discussed
http://social.technet.microsoft.com/Forums/en-US/ilm2/thread/9551bd05-333c-4f43-a967-3d7642ed4f38
Thx a lot to all of you
Free Windows Admin Tool Kit Click here and download it now
May 11th, 2011 4:17am