Custom Activity using EnumerationResourceActivity
Hy, my need is to build DisplayName from LastName.
_displayName=lastName+1.toString()
I want to search if already exist displayname and increment it.
I use Carol (maybe she is reading) example
http://www.wapshere.com/missmiis/generate-unique-attribute-activity
but I've some problem.
First I've no result in
enumerateResourcesActivity1.TotalResultsCount > 0
so I use
ResourceType resource = EnumerateResourcesActivity.GetCurrentIterationItem((CodeActivity)sender) as ResourceType;
if (resource != null)
{
...
}
but in this case for each while loop I find always same resource even if I change my xpath query
private void InitializeResource_ExecuteCode(object sender, EventArgs e)
{
enumerateResourcesActivity1.ActorId = new Guid(FIMADMIN_GUID);
string resourceType = "Person";
enumerateResourcesActivity1.Selection = new string[] { "DisplayName", "AccountName" };
enumerateResourcesActivity1.XPathFilter = "/" + resourceType + "['" + destinationAttribute + "' = " + CalculateId() + "]";
}
Mow my example fits well with Carol example but I think enumeration block hide some secret to me.
Another strange thing is that during debug after the initalizeresourceactivity is executed enumerateresourceActivity and then the sequence restart..but why?
There are some example to use enumeration block in while block in which the while block is used to chenge xpath filter of enumeration?
thx a lot for help.
PS:I've already read all post about enumeration but no resolution.
July 7th, 2011 4:27pm
Hi,
I think this script should run correctly even if it doesn't use enumeration.
Good Luck.
Jean-Michel
$FIMServer="localhost"
$URI = "http://" + $FIMServer + ":5725/ResourceManagementService"
$firstname="A A","B B","A A"
if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {add-pssnapin FIMAutomation}
$fimSession = New-FIMSession -Credential (Get-Credential) -Server $FIMServer
$type="Person"
$attribute1="DisplayName"
$attribute2="FirstName"
foreach($elt in $firstname){
$answer=0
$count=1
while ($answer -eq 0)
{
$valFirst=$elt
$valLast=$valfirst+($count).toString()
$filter = "/" + $type + "[" + $attribute1 + "='" + $valLast + "']"
write-output -msg "`nSearching on $filter"
$user = Get-FIMResource -Filter $filter -Session $fimSession
if ($user -ne $null){
write-output "$valFirst $valLast found, following"
$count+=1
}
else {
write-output "$valFirst $valLast not found"
$answer=1
$count=1
# Create new user
New-FIMResource -Type $type -Session $fimSession -Attributes @{$attribute1=$valLast; $attribute2=$valFirst}
}
}
}
write-output -msg "`n------------ END ----------------"
Free Windows Admin Tool Kit Click here and download it now
July 7th, 2011 5:19pm
ok I think the script will run greatly, but I need to accomplish this task using custom activity..
So Carol example suits well, but I've experienced some difficoult to implement it.
Thaks
Regards.
Luka.
July 7th, 2011 5:45pm
can you post your workflow code here?
Free Windows Admin Tool Kit Click here and download it now
July 7th, 2011 6:50pm
Hi-
Since you don't need to inspect the enumeration results, this is pretty easy to do. Here's what my username generator code looks like with respect to this:
// create the XPath filter to search FIM with
private void codeSetupEnumerationActivity_ExecuteCode(object sender, EventArgs e)
{
currentUsername = GenerateUsername(readResourceActivity.Resource["FirstName"] as string, readResourceActivity.Resource["LastName"] as string);
enumerateResourcesActivity1_XPathFilter1 = String.Format(CultureInfo.InvariantCulture, "/{0}[{1} = '{2}']", UniquenessTestClass, UniquenessTestAttribute, currentUsername);
}
private void codeCheckEnumerationResults_ExecuteCode(object sender, EventArgs e)
{
if (enumerateResourcesActivity1.TotalResultsCount > 0)
foundUniqueValue = false;
else
foundUniqueValue = true;
}
In the first code block, note that we're setting a dependency property, not the properties of the activity directly. I don't remember exactly why I had to do this, but it's what works. You can go in the WF designer and promote the XPathFilter property of the
activity to a dependency property.
My Book - Active Directory, 4th Edition
My Blog - www.briandesmond.com
July 7th, 2011 8:48pm
In addition to the other comments don't forget about activity execution context. When you use a WhileActivity or ReplicatorActivity the updates to class properties are maintained within an execution context, i.e. this.something won't hold the value.
You need to get the value from within the context, here's an example:
private void prepareFimExistenceCheck_ExecuteCode(object sender, EventArgs e)
{
string existenceCheckXPath = String.Format("/Person[AccountName='{0}']", this.currentName.ToLower());
//this.activityLog.Log("Generated XPath. Adding to EnumerateResource activity.");
// this code activity resides within an IfElseBranchActivity (which in turn resides
// within an IfElseActivity that resides in a SequenceActivity within a WhlieActivity.
// the EnumerateResourcesActivity also exists within the IfElseBranchActivity which must
// be accessed via the correct ActivityExecutionContext because it is a child of the
// while activity. GetActivityNyName(String) fails to retrieve the correct AEC unless
// the provided "query" is the fully qualified name, ergo we must retrieve first the qualified
// name of the parent activity and then replace the parent-specific portion of the name
// with that of the activity we wish to reference.
// See ActivityExecutionContext for more information.
CodeActivity thisActivityInstance = sender as CodeActivity;
IfElseBranchActivity parent = (IfElseBranchActivity)thisActivityInstance.Parent;
String enumerateResourceQualifiedName = parent.QualifiedName.Replace(parent.Name, "queryFimForExistence");
EnumerateResourcesActivity enumTarget = (EnumerateResourcesActivity)parent.GetActivityByName(enumerateResourceQualifiedName);
enumTarget.XPathFilter = existenceCheckXPath;
this.activityLog.Log("The following XPath will be used to query FIM: " + enumTarget.XPathFilter);
this.activityLog.Log("Checking uniqueness...");
this.activityLog.Log("Querying FIM...");
}
I may have done a rubbish job of explaining that. Here's some more info.:
http://msdn.microsoft.com/en-us/magazine/cc163414.aspx
Free Windows Admin Tool Kit Click here and download it now
July 8th, 2011 10:18am
Hi-
Since you don't need to inspect the enumeration results, this is pretty easy to do. Here's what my username generator code looks like with respect to this:
// create the XPath filter to search FIM with
private void codeSetupEnumerationActivity_ExecuteCode(object sender, EventArgs e)
{
currentUsername = GenerateUsername(readResourceActivity.Resource["FirstName"] as string, readResourceActivity.Resource["LastName"] as string);
enumerateResourcesActivity1_XPathFilter1 = String.Format(CultureInfo.InvariantCulture, "/{0}[{1} = '{2}']", UniquenessTestClass, UniquenessTestAttribute, currentUsername);
}
private void codeCheckEnumerationResults_ExecuteCode(object sender, EventArgs e)
{
if (enumerateResourcesActivity1.TotalResultsCount > 0)
foundUniqueValue = false;
else
foundUniqueValue = true;
}
In the first code block, note that we're setting a dependency property, not the properties of the activity directly. I don't remember exactly why I had to do this, but it's what works. You can go in the WF designer and promote the XPathFilter property of the
activity to a dependency property.
My Book - Active Directory, 4th Edition
My Blog - www.briandesmond.com
Absolutely right.
I always set property of the activity direct instead of dependency property.
Thanks a lot!
Berst regards.
Luka.
July 8th, 2011 11:29am
Ok, I will remember activity execution context, in fact I've bookmarked your site :)
Thanks a lot.
Best Regards.
Luka.
Free Windows Admin Tool Kit Click here and download it now
July 8th, 2011 11:33am
It doesn't matter whether you set a property of the activity or the dependency property that is set for the activity. What matters is the activity execution context.
July 8th, 2011 3:18pm