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"}


