The first custom workflow activity I wrote was one to select a unique value from a list of possible values placed in WorkflowData variables. I’ve now re-written this as a PowerShell script to use with the open source FIM PowerShell activity.
The script here just checks again the Portal, but it would be a simple modification to make it check against AD instead/as well.
Setting up the Workflow
First you have to get the FIM PowerShell activity installed. See here for the extra steps I did to get it working with the FIM PowerShell cmdlets.
The script expects to find one or more options in WorkflowData parameters. Here is what the Workflow definition looks like:
The options are just Function Evaluators:
Then the FIM PowerShell activity calls my script:
The Script
### ### Generate Unique ### ### Called using FIMPowershell Workflow Activity. ### Parameters: ### -ObjectType The Object Type to be checked ### -AttributeName The Attribute to be checked for uniqueness ### -LogFile Verbose logging to a log file if specified ### ### WorkflowData: The FIM Workflow must provide one or more WorkflowData values to be checked in turn. ### ### The first unique option found will be written back to \\Target\AttributeName ### PARAM($ObjectType,$AttributeName,$LogFile) ### Get FIMPowershell.ps1 from http://technet.microsoft.com/en-us/library/ff720152(v=ws.10).aspx . E:\FIM\scripts\FIMPowerShell.ps1 ### The password for the account to use running the scripts must be saved to a file readable by the FIM Service account. ### Execute the following command as the FIM Service account: ### read-host -assecurestring | convertfrom-securestring | out-file encrypted.txt $PWFile = 'E:\FIM\scripts\WF\encrypted.txt' $AdminAccount = "fimadmin" if ($LogFile -ne $null) {$Verbose = $true} else {$Verbose = $false} if ($Verbose) {get-date | out-file -FilePath $logFile -encoding "Default"} ## ## Create credential to use when running commands against the FIM service ## if ($Verbose) {"Creating credential object for account $AdminAccount" | add-content $logFile} $password = get-content $PWFile | convertto-securestring $UserCredential = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist $AdminAccount,$password ### ### Get the Request Details ### if (-not $fimwf) { $msp = "Failed to get workflow details from the FIM Request" if ($Verbose) {"Error: " + $msg | add-content $logFile} Throw $msg } $ReqGUID = $fimwf.RequestId.Guid if ($Verbose) {"RequestID: $ReqGUID" | add-content $logFile} $TargetGUID = $fimwf.TargetId.Guid if ($Verbose) {"Target: $TargetGUID" | add-content $logFile} ### ### Get the WorkflowData ### if ($Verbose) {"Getting WorkflowData" | add-content $logFile} if ($Verbose) {$fimwf.WorkflowDictionary | Out-String -Width 100 | add-content $logFile} $options = $fimwf.WorkflowDictionary foreach ($option in $options.Values) { $filter = "/" + $ObjectType + "[" + $AttributeName + "='" + $option + "']" $obj = Export-FimConfig -Custom ($filter) -OnlyBaseResources -Credential $UserCredential if ($obj -eq $null) { $returnOption = $option if ($Verbose) {"$option is unique" | add-content $logFile} break } else { if ($Verbose) {"$option is not unique" | add-content $logFile} } } if ($returnOption -ne $null) { if ($Verbose) {"Updating Target $AttributeName with value $returnOption" | add-content $logFile} $importObject = ModifyImportObject -TargetIdentifier $TargetGUID -ObjectType $ObjectType SetSingleValue $importObject $AttributName $returnOption $importObject | Import-FIMConfig -Credential $UserCredential } else { Throw "Failed to find a unique value"}