Something that crops up pretty frequently is the request to include who approved or rejected an approval in the resultant e-mail notification sent by the approval activity. Frustratingly this wasn’t possible in FIM 2010 and required a custom approval activity. In FIM R2 the out-of-box approval activity adds three elements to the workflow instance’s dictionary:
- ApprovalCompletedBy
- ApprovalFinalStatus
- Reason
Information on this little-known gem can be found in the What’s New in Forefront Identity Manager 2010 R2 TechNet page. I’m going to re-post the info. here and provide a basic example.
Note.
Technically four WF keys are available however the fourth, Cause, has been deprecated.
First things first: the workflow dictionary. Every workflow instance maintains a dictionary for the life of the instance. Activities share information via this Dictionary (Dictionary<String, Object>). Various activities allow you to access the value of a key of the dictionary via the lookup grammar [//WorkflowData/KeyName]. Where KeyName is the name of the key –the String in the Dictionary<String,Object>.
ApprovalCompletedBy
Adding [//WorkflowData/ApprovalCompletedBy] into your notification activity (or some custom activity) will give you one of the following:
- If the approval is approved this data provides the list of names that approved the request.
- If the approval is rejected this data provides the list of names that rejected the request.
ApprovalFinalStatus
Adding [//WorkflowData/ApprovalFinalStatus] gives you the status of the approval:
- Approved
- Rejected
- TimedOut
Reason
Adding [//WorkflowData/Reason] gives you one of the following strings:
- Approval has expired. See the approval details for this request for more information.
- Approval was rejected. One of the approvers is not valid.
- Approver does not have the authority to approve anymore.
Examples
As a quick example of this in action I’m going to create a new e-mail template that makes use of some of these properties. I’m going to use the Default completed approval email template as my starting point. I’ll create a new e-mail template called Customised completed approval email template. I’m going to copy the template type and subject from the Default completed approval email template without making any changes. I’m going to make the following changes to the body of the default template:
<!-- Added //wf/approvalFinalStatus in place of --> <p class="MsoNormal">The following Request does not require any further action. The Request has been [//WorkflowData/ApprovalFinalStatus].</p> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal"><b>Requestor:</b></p> <p class="MsoNormal">[//Requestor/DisplayName] ([//Requestor/Email])</p> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal"><b>Request submitted on:</b></p> <p class="MsoNormal">[//Request/CreatedTime] (GMT)</p> <p class="MsoNormal"><o:p> </o:p></p> <!-- Added //wf/approvalCompletedBy --> <p class="MsoNormal"><b>Approver/rejector:</b></p> <p class="MsoNormal">[//WorkflowData/ApprovalCompletedBy]</p> <p class="MsoNormal"><o:p> </o:p></p>
Basically I changed this element:
<p class="MsoNormal">The following Request does not require any further action. The Request has been approved or rejected, or the approval activity for this Request has expired.</p>
To this:
<p class="MsoNormal">The following Request does not require any further action. The Request has been [//WorkflowData/ApprovalFinalStatus].</p>
And added this:
<!-- Added //wf/approvalCompletedBy --> <p class="MsoNormal"><b>Approver/rejector:</b></p> <p class="MsoNormal">[//WorkflowData/ApprovalCompletedBy]</p> <p class="MsoNormal"><o:p> </o:p></p>
The result of this customisation is as follows:
That is quite a lot more informative in my opinion.