First published on MSDN on Jun 19, 2015
Introduction to Workflows
Workflows within the FIM Portal are used in combination with Sync rules to build, manage, control, or manipulate data that. Prior to the FIM Portal any manipulation of data from one data source to be managed to or from another data source need Custom Rules Extensions that required an understanding of Visual Basics or C#, which often required onsite developers or 3rd party consultants that are often expensive and hard to come by. One of the many issues with having to use Rules Extensions to manage data was scalability, maintenance or troubleshooting. After the rules extensions are in place if a need arises where a change needs to be implemented it would once again require onsite developers or at that point someone with a basic knowledge of VB and or C# to understand the existing Rules Extension in order to make the necessary changes. The worst possible scenario is where a change is needed in the Rules Extension and the source code is nowhere to be found for one reason or another. Workflows are used to perform a variety of different task which include but certainly not limited Notification when a specific action has taken place, Authorization when someone would like to make a change to a specific attribute, or actions such as completing a function on behalf of the user when a specific action has taken place. A combination of all these different task can be performed for any desired circumstance. In the end Workflows are put in place for automation of your environment as well as streamlining your organization’s processes. More importantly these workflows can be used to follow a specific standard such as naming conventions and applying appropriate permissions.
Often when these steps are performed manually they are done incorrectly and not necessarily by incompetence but by common mistakes like Typos, or forgetfulness. Workflows by them-selves do nothing but when they are associated with an MPR (Management Policy Rule) they can be used to perform functions as mentioned previously. These same workflows can be associated with multiple MPR’s but it is important to understand what the workflows are doing and when they should be “Triggered” or “Applied”. If not properly planned and tested you could find yourself in a looping scenario where a workflow gets applied again and again because the action that the workflow performs is associated with a “trigger” that applies the workflow. For example if you have a workflow that builds a display name but the MPR that “triggers” the workflow is for multiple attribute such as Create and Modify First Name, Last Name, or Display Name than the very action being performed would build or modify the objects Display Name, which would cause the workflow to be triggered a second time where even if the 2nd result would build the same Display Name and there may not be a change its still wasted resources on your machine, and additional unnecessary SQL “Churn”. Other situations could exist where the workflow gets in an endless loop which would eventually slow your environment to a crawl. Bottom line is to be sure and test any and all workflows before they are put in production.
Workflow Types
When you first install the Forefront Identity Manager Portal you are given 3 Types to choose Each Workflow type having additional functions associated with that particular activity. Additionally there is a select Run On Policy Update which is used in conjunction with Transition Set MPR’s

The 3 Workflow Types
-
Authentication
-
Lockout Gate
-
One-Time Password Email Gate
-
One-Time Password SMS Gate
-
Password Gat
-
QA Gate
Authorization
-
Approval
-
Filter Validation
-
Function Evaluator
-
Group Validation
-
Notification
-
Requestor Validation
Action
-
Active Directory Password Reset Activity
-
Function Evaluator
-
Notification
-
Synchronization Rule Activity
Working with the Default Workflow library
The following information is directly from the following Link.
(References TechNet Article
http://technet.microsoft.com/en
–
us/library/ff800820(v=WS.10).aspx)
Configuring
attribute flow mappings is an elementary task when configuring synchronization rules. The simplest form of an attribute flow mapping is a direct mapping. As indicated by the name, a direct mapping takes the value of a source attribute and applies it to the configured destination attribute. There are cases where you either need existing attribute values to be modified or new attribute values to be calculated before the system applies them to a destination.
Functions are a built-in method used to define the type of modification you need the synchronization engine to apply when generating an attribute value for an object.
In FIM, you can group the existing functions into the following categories:
-
Data Manipulation Functions.
- Functions to perform a variety of manipulation operations on strings.
Data Retrieval Functions.
- Functions to extract data from attribute values.
Data Generation Functions.
- Functions to generate values.
Logic Functions.
- Functions to perform operations based on conditions.
Data Manipulation Functions
- Data manipulation functions are used to perform a variety of manipulation operations on strings.
| Concatenate
|
Description
| The
Concatenate
function is used to concatenate two or more strings. |
Function Signature
| string1 + string2 + … |
Inputs
| Two or more strings |
Operations
| All input string parameters are concatenated with each other. |
Output
| One string |
| UpperCase
|
Description
| The
UpperCase
function converts all characters in a string to upper
case. |
Function Signature
| String UpperCase(string) |
Inputs
| One string |
Operations
| All lower case characters of the input parameter are
converted to upper case characters. Example: UpperCase(“test”) results
in “TEST”. |
Output
| One string |
| LowerCase
|
Description
| The
LowerCase
function converts all characters in a string to lower
case. |
Function Signature
| String LowerCase(string) |
Inputs
| One string |
Operations
| All upper case characters of the input parameter are converted to lower case characters. Example: LowerCase(“TeSt”) results in “test”. |
Output
| One string |
| Proper Case
|
Description
| The
ProperCase
function coverts the first character of each
space-delimited word in a string to upper case and all other characters are
converted to lower case. |
Function Signature
| String ProperCase(string) |
Inputs
| One string |
Operations
| The first character of every space-delimited word in the input parameter is converted to upper case, and all upper case characters are converted to lower case characters. If a word in the input parameter starts with a non-alphabet character, the first character of the word is not converted to upper case. Examples: -
ProperCase(“TEsT”) results in “Test”. -
ProperCase(“britta simon”) results in “Britta Simon”. -
ProperCase(“TEsT”) results in “ Test”. -
ProperCase(“$TEsT”) results in “$Test”.
|
Output
| One string |
| LTrim
|
Description
| The
LTrim
function removes leading white spaces from a string. |
Function Signature
| String LTrim(string) |
Inputs
| One string |
Operations
| The leading white space characters contained in the input parameter are removed. Example: LTrim(“ Test ”) results in “Test ”. |
Output
| One string |
| RTrim
|
Description
| The
RTrim
function removes trailing white spaces from a string. |
Function Signature
| String RTrim(string) |
Inputs
| One string |
Operations
| The trailing white space characters contained in the input parameter are removed. Example: RTrim(“ Test ”) results in “ Test”. |
Output
| One string |
| Trim
|
Description
| The
Trim
function removes leading and trailing white spaces from a
string. |
Function Signature
| String Trim(string) |
Inputs
| One string |
Operations
| The leading and trailing white space characters contained
in the string are removed. Example: Trim(“ Test ”) results in
“Test”. |
Output
| One string |
| RightPad
|
Description
| The
RightPad
function right-pads a string to a specified length by using a provided padding character. |
Function Signature
| String RightPad(string, length, padCharacter) |
Inputs
| -
string.
The string to pad. -
length.
An integer representing the desired length of string. -
padCharacter.
A string that consist of a single character to be used as a pad character.
|
Operations
| If the length of
string
is less than
length
, then
padCharacter
is repeatedly appended to the end of
string
until it has a length equal to
length
. Examples: - RightPad(“User”,10, “0”) would result in “User000000”.
- RightPad(RandomNum(1,10),5, “0”) could result in “9000”.
Note: padCharacter
can be a space character, but it cannot be a null value. If the length of
string
is equal to or greater than
length
,
string
is returned unchanged. |
Output
| If
string
has a length greater than or equal to
length
, a string identical to
string
is returned. If the length of
string
is less than
length
, then a new string of the desired length is returned containing
string
padded with a
padCharacter
. If
string
is null, the function returns an empty string. |
| LeftPad
|
Description
| The
LeftPad
function left-pads a string to a specified length by using a provided padding character. |
Function Signature
| String LeftPad(string, length, padCharacter) |
Inputs
| -
string.
The string to pad. -
length.
An integer representing the desired length of string. -
padCharacter.
A string that consists of a single character to be used as pad character.
|
Operations
| If the length of
string
is less than
length
, then
padCharacter
is repeatedly appended to the beginning of
string
until it has a length equal to
length
. Examples: - LeftPad(“User”,10, “0”) would result in “000000User”.
- LeftPad(RandomNum(1,10),5, “0”) could result in “0009”.
Note: padCharacter
can be a space character, but it cannot be a null value. If the length of
string
is equal to or greater than
length
,
string
is returned unchanged. |
Output
| If
string
has a length greater than or equal to
length
, a string identical to
string
is
returned. If the length of
string
is less than
length
, then a new string of the desired length is returned containing
string
padded with a
padCharacter
. If
string
is null, the function returns an empty string. |
| BitOr
|
Description
| The
BitOr
function sets a specified bit on a flag to 1. |
Function Signature
| Int BitOr(mask, flag) |
Inputs
| -
mask.
A hexadecimal value that specifies the bit to set on the flag. -
flag.
A hexadecimal value that is to have a specific bit modified.
|
Operations
| This
function converts both parameters to binary representation and compares them:
-
Sets a bit to 1 if one or both of the corresponding bits
in
mask
and
flag
are 1 and to 0 if both of the corresponding bits are 0. -
It returns 1 in all cases except where the corresponding
bits of both parameters are 0. -
The
resulting bit pattern is the “set” (1 or true) bits of any of the
two operands. Multiple flag bits can be set if multiple bits have the value 1
in
mask
.
|
Output
| A new version of
flag
, with the bits specified in
mask
set to 1. |
| BitAnd
|
Description
| The
BitAnd
function sets a specified bit on a flag to 0. |
Function Signature
| Int BitOr(mask, flag) |
Inputs
| -
mask.
A hexadecimal value that specifies the bit to modify on the flag. -
flag.
A hexadecimal value that is to have a specific bit modified.
|
Operations
| This function converts both parameters to binary representation and compares them: - Sets a bit to 0 if one or both of the corresponding bits in
mask
and
flag
are 0 and to 1 if both of the corresponding bits are 1. - It returns 0 in all cases except where the corresponding bits of both parameters are 1. Multiple flag bits can be set to 0 if multiple bits have the value 0 in
mask
.
|
Output
| A new version of
flag
with the bits specified in
mask
set to 0. |
| DateTimeFormat
|
Description
| The
DateTimeFormat
function is used to format a DateTime in string form to a specified format. |
Function Signature
| String DateTimeFormat(dateTime, format) |
Inputs
| -
dateTime.
A string representing the DateTime to format. -
format.
A string representing the format to convert to.
|
Operations
| The
format
string specified in
format
is applied to the
DateTime
in the
dateTime
string. The string specified in
format
must be a valid
DateTime
format. If it is not, an error is returned indicating that the format is not a valid
DateTime
format. Note:
For the characters accepted to create user-defined formats, see
User
–
Defined
Date/Time Formats (Format Function)
http://go.microsoft.com/fwlink/?LinkId=195182. Example: DateTime(“12/25/2007”, “yyyy-MM-dd”) results in “2007-12-25”. |
Output
| A string resulting from applying
format
to
dateTime
. |
| ConvertSidToString
|
Description
| The
ConvertSidToString
converts a byte array containing a security identifier to a string. |
Function Signature
| String ConvertSidToString(ObjectSID) |
Inputs
| ObjectSID.
A byte array containing a security identifier (SID). |
Operations
| The specified binary SID is converted to a string. |
Output
| A string representation of the SID. |
| ConvertStringToGuid
|
Description
| The
ConvertStringToGuid
function converts the string representation of a GUID to a binary representation of the GUID. |
Function Signature
| Byte[] ConvertStringToGuid(stringGuid) |
Inputs
| Guid.
A string formatted in this pattern:
xxxxxxxx
–
xxxx
–
xxxx
–
xxxxxxxxxxxxxxxx
, where the value of the GUID is represented as a series of hexadecimal digits in groups of 8, 4, 4, 4, and 12 digits and separated by hyphens. An example of a return value is “382c74c3-721d-4f34-80e557657b6cbc27”. |
Operations
| The string
Guid
specified in parameter 1 is converted to its binary representation. If the string is not a representation of a valid
Guid
, the function rejects the argument with the following error: The parameter for the ConvertStringToGuid function must be a string representing a valid Guid.
|
Output
| A binary representation of the
Guid
. |
| ReplaceString
|
Description
| The
ReplaceString
function replaces all occurrences of a string to another string. |
Function Signature
| String ReplaceString(string, OldValue, NewValue) |
Inputs
| -
String.
A string in which to replace values. -
OldValue.
The string to search for and to replace. -
NewValue.
The string to replace to.
Note: NewValue
can be an empty string “”. Neither
String
nor
OldValue
can be empty. |
Operations
| All occurrences of
OldValue
in the string are replaced with
NewValue
. The function must be able to handle the following special characters: -
n.
New Line. -
r.
Carriage Return. -
t.
Tab.
Example: ReplaceString(“OnenrMicrosoftnrWay”,”nr”,” “) returns “One Microsoft Way”. |
Output
| A string with all occurrences of
OldValue
in the string replaced with
NewValue
. |
| Mid
|
Description
| The
Mid
function returns a specified number of characters from a
specified position in a string. |
Function Signature
| String Mid(string, pos, numChars) |
Inputs
| -
string.
The string from which to return characters. -
pos.
A number identifying the starting position in a string for returning characters. -
numChars.
A number identifying the number of characters to return from a position in the string.
|
Operations
| Return
numChars
characters starting from position
pos
in the string. Example: Mid(“Britta Simon”, 3, 5) would return “itta ”. |
Output
| A string containing
numChars
characters from position
pos
in a string: - If
numChars
= 0, return an empty string. - If
numChars
< 0, return an empty string. - If
pos
> the length of
string
, return an input string. - If
pos
≤ 0, return an input string. - If
string
is null, return an empty string.
If there are no
numChar
characters remaining in
string
from position
pos
, as many characters as can be
returned are returned. |
Data generation functions
Data generation functions are used to generate values for specific data types.
| CRLF
|
Description
| The
CRLF
generates a Carriage Return/Line Feed. You use this function
to add a new line. |
Function Signature
| String CRLF |
Inputs
| No parameters |
Operations
| A CRLF is returned. Example: AddressLine1 + CRLF() + AddressLine2 results in: -
AddressLine1
-
AddressLine2
|
Output
| A CRLF is the output. |
Logic Functions
Logic functions are used to perform an operation based on conditions evaluated by the system.
| IIF
|
Description
| The
IIF
function returns one of a set of possible values based on a specified condition. |
Function Signature
| Object IIF(condition, valueIfTrue, valueIfFalse) |
Inputs
| -
Condition.
Any value or expression that can be evaluated to true or false. -
valueIfTrue
A value that is returned if the condition evaluates to true. -
valueIfFalse
A value that is returned if the condition evaluates to false.
The following are functions available for use as expressions in the IIF function as
condition
:
Eq.
This function compares two
arguments for equality. NotEquals.
This function compares two arguments for inequality, returning true if they are
not equal and false if they are equal. Example: NotEquals(EmployeeType, “Contractor”) LessThan.
This function compares two numbers, returning true if the first is less than the
second and false otherwise. Example: LessThan(Salary, 100000) GreaterThan.
This function compares two numbers, returning true if the first is greater than
the second and false otherwise. Example: GreaterThan(Salary, 100000) LessThanOrEquals.
This function compares two numbers, returning true if the first is less than or equal to the second and false otherwise. Example: LessThanOrEquals(Salary, 100000) GreaterThanOrEquals.
This function compares two numbers, returning true if the first is greater than or is equal to the second and false otherwise. Example:
GreaterThanOrEquals(Salary, 100000) |
| IsPresent.
This function takes as input an
attribute in the ILM schema and returns true if the attribute is not null and
false if the attribute is null. |
Operations
| If
condition
evaluates to true, return
valueIfTrue
.
Otherwise return
valueIfFalse
. Example: IIF(Eq(EmployeeType,”Intern”),”t-“ + Alias,
Alias)returns the alias of a user with “t-“ added to the beginning of it if
the user is an intern. Otherwise, it returns the user’s
alias as is. |
Output
| The output is
valueIfTrue
if the condition is true or
valueIfFalse
if the condition is false. |
Now that you are at least a bit more familiar with working with the Default Workflows within the FIM Portal, you may wish to begin understanding Advanced Work Flows which utilize Custom Workflow Activities built with the .NET Framework.
Understanding Advanced Workflows (Coming Soon)