Many times, we end up having some pending exports to Active Directory Domain Services during FIM deployments. If those changes are few, then using the synchronization manager to go over them one by one is a convenient method. However, it would not be convenient if we had a large number of changes.

While it is possible to export those changes to an XML log file, looking at an XML tree is not very intuitive to everyone. In this post, I will show you how I used eXtensible Stylesheet Language (XSLT) to transform our exported XML document to a tabular format.

Create a Log File Using Export Run Profile

To export pending changes to a log file, you will need to do the following:
  1. Launch the Synchronization Service Manager
  2. Click on your Active Directory Domain Services MA (ADMA)
  3. On the right hand side, click "Configure Run Profiles"
  4. Click "New Profile..."

  1. Provide a name for this profile "Export to a log file"
  2. Choose type Export
  3. Click "Set Log File Options"
  4. Choose "Create a log file and stop the run. Do not export to data source. (test only)"
  5. Type the name of the file

  1. Click Ok
  2. Click Next
  3. Select a Partition, and click finish, then OK
Now, whenever you have a large number of changes you need to review and run this profile. You can run this profile, and find the log file under "MaData folder". If you installed FIM in the default location, then it will be here "C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\MaData\<MA Name>".

Using the XSLT with your XML log file

The idea here is to transform the exported XML log file into a nice view for everyone to look at. This is important because changes to Active Directory need to be verified and validated for correctness. Some changes, if not reviewed, can have hazardous effect in a production system. Group membership changes is one example.

The following XML is a result of an export from a test environment.

<?xml version="1.0" encoding="UTF-16"?>
<?xml-stylesheet type="text/xsl" href="/TransformIt.xsl"?>
<mmsml xmlns="" step-type="export">
    <delta operation="update" dn="CN=Richardson\, Cynthia,OU=User Accounts,DC=zeva,DC=fim" newdn="CN=Richardson\, Cynthia,OU=FIM,OU=Disabled Users,DC=zeva,DC=fim">
      <anchor encoding="base64">zrhAXN2xhkabVubSXF7uiQ==</anchor>
      <attr name="userAccountControl" operation="update" type="integer" multivalued="false">
        <value operation="delete">0x200</value>
        <value operation="add">0x202</value>
    <delta operation="delete" dn="CN=Roberts\, Craig,OU=FIM,OU=Disabled Users,DC=zeva,DC=fim">
      <anchor encoding="base64">XEneeCZ4B06XGALDsYSrdw==</anchor>
    <delta operation="update" dn="CN=Test Group 1,OU=Dynamic,OU=FIMNABOXGroups,DC=zeva,DC=fim">
      <anchor encoding="base64">iggzf9vk+EyCOHVdQ7zcsg==</anchor>
      <dn-attr name="member" operation="add" multivalued="true">
          <dn>CN=Simon\, Britta,OU=User Accounts,DC=zeva,DC=fim</dn>
          <anchor encoding="base64">Imibf3GvqEOT/D50D3t4rA==</anchor>
    <delta operation="add" dn="CN=White\, Wade,,OU=User Accounts,DC=zeva,DC=fim">
      <dn-attr name="homeMDB" multivalued="false">
          <dn>CN=User-Mail-8,CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups.....</dn>
          <anchor encoding="base64">vhX2Dmd+90+Ngp9kQmvNrA==</anchor>
      <dn-attr name="manager" multivalued="false">
          <dn>CN=Pitt\, John,OU=User Accounts,DC=zeva,DC=fim</dn>
          <anchor encoding="base64">3n8M/DeLJkOB2RLKa6Ydyg==</anchor>
      <attr name="description" type="string" multivalued="true">
        <value>New hire</value>
      <attr name="displayName" type="string" multivalued="false">
        <value>White, Wade</value>
      <attr name="givenName" type="string" multivalued="false">
      <attr name="mDBUseDefaults" type="boolean" multivalued="false">
      <attr name="mailNickname" type="string" multivalued="false">
      <attr name="msExchHomeServerName" type="string" multivalued="false">
        <value>/o=ZEVAK/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=ZEVAEXMB05</value>
      <attr name="pwdLastSet" type="integer" multivalued="false">
      <attr name="sAMAccountName" type="string" multivalued="false">
      <attr name="sn" type="string" multivalued="false">
      <attr name="userAccountControl" type="integer" multivalued="false">
      <attr name="userPrincipalName" type="string" multivalued="false">

To be able to format your exported xml file, you will need to follow the instructions below:

  1. Download the XSLT file from the link here
  2. Copy it to the same folder where your XML log file is located
  3. Modify your XML file by
    • Adding a reference for the XSLT
      <?xml-stylesheet type="text/xsl" href="/TransformIt.xsl"?>
    • Modify the following tag by removing "xmlns" attribute from it
      <mmsml xmlns="" step-type="export">
  1. Open your XML log file in a web browser such as Internet Explorer (IE) and you will find your XML now nicely formatted to look at. It is also searchable. Using (IE) you can search for keywords, and they will be highlighted for you.
The following screenshot shows the final results after applying an XSLT file to the XML log file.


In this post, we discussed how to utilize XSLT to transform ADMA exported XML log file into a nice tabular format for people to review. The XSLT applies only to Active Directory exported changes. You can use it on other management agent, however, I will not guarantee results. Perhaps future release to the XSLT file will include other MAs. If you have feedback on how to make it look better, please don't hesitate to write a comment below. I will make sure to implement it and provide a new version of the XSLT file.

One of the draw backs of using this approach is it doesn't show deleted values. Also, it doesn't show attributes of deleted objects. It is very good to use to review attributes updates, and make sure they are correct.


The BHOLD/FIM integration component introduces a self-service portal to request proposed roles. Proposed roles are those that are not yet activated for a user, still available for the user to request them. The request to activate a role in BHOLD/FIM integration leverages FIM approval workflows. This is a big plus, since FIM Administrators will deal with a familiar interface (FIM Portal) to manage their workflows and requests. In addition to that, all user requests can be found in one place under "Manage My Requests".

In this post, we will discuss what is available out of the box from BHOLD (after installing the integration component) and where to find information about that. We will also discuss how to create a Non-BHOLD approval process for BHOLD role requests.

This post assumes you know how to configure FIM policies including Management Policy Rules, Workflows, and Sets. If you don't, the links below are good introduction to know more about this topic.
Also, the post assumes you have the basic knowledge of creating a BHOLD role and link it to an OU.

Out of the box objects

The FIM Service schema gets extended, and "BHOLD_ROLE" is a new resource type that gets created in FIM Service. When a user submit a request to activate a role, a new "BHOLD_ROLE" objects is created or an existing object is modified.

"BHOLD_ROLE" resource type has attributes bound to it. Some of those attributes will determine the authorization workflow that FIM will execute. Those attributes are highlighted in the image below:

The following links discuss the role approval process in BHOLD FIM Integration. They provide a details on how you can configure approval the BHOLD way.

The above attributes are then used in sets filters. The following sets gets created. They use the above highlighted attributes:
Set's DisplayName
_BHOLD ROLE Management - All roles with approval
_BHOLD ROLE Management - All roles with line management approval
_BHOLD ROLE Management - All roles with role management approval
_BHOLD ROLE Management - All roles with security office approval
_BHOLD ROLE Management - All roles without approval

The following workflows gets created:
Workflow stage
_BHOLD ROLE Management - Line Management ApprovalAuthorization
_BHOLD ROLE Management - Role Management ApprovalAuthorization
_BHOLD ROLE Management - Security Office ApprovalAuthorization
_BHOLD ROLE Management - Without ApprovalAuthorization
BHOLD_ROLE Title GeneratorAuthorization

The following MPRs gets created:
Display Name
Action Type
Grant Right
_BHOLD_ROLE Line Management - ApprovalModifyNoYesNoYesNo
_BHOLD_ROLE Line Management - Without ApprovalModifyNoYesNoNoNo
_BHOLD_ROLE Role Management - ApprovalModifyNoYesNoYesNo
_BHOLD_ROLE Security Office - ApprovalModifyNoYesNoYesNo
BHOLD: Administrators can read and update BHOLD rolesAllNoYesNoNoNo
BHOLD_ROLE Title GeneratorModifyNoYesNoYesNo

The reason I'm showing you all those MPRs and workflows is for you to get a notion of what's going on here. It's the same exact approach we have been using for so long in FIM. The same way you configure a workflow to approve creating a new group, can be used when requesting to activate a role. In the next section, we will discuss how to create a non-BHOLD approval process for BHOLD.

Non-BHOLD Approval Process

First off, you need to do is to group together similar "BHOLD_ROLE" objects in a set. The above sets are useful and can be used, however, we will use different attributes. For the sake of this post, we will use the attribute DisplayName. The set criteria will be (DisplayName starts with "MyRole").

Second, you need to create the approval workflow. For the sake of this example, the approver will be the [//Requestor/Manager]. After the workflow has been created, you will need to modify the XOML to include the BHOLD DLL in the definition. Here's how it needs to look like. If you didn't add this reference to this DLL, the approval process will be triggered, however the role will not be activated in BHOLD.

1.<ns0:SequentialWorkflowActorId="00000000-0000-0000-0000-000000000000"RequestId="00000000-0000-0000-0000-000000000000"    x:Name="SequentialWorkflow"TargetId="00000000-0000-0000-0000-000000000000"WorkflowDefinitionId="00000000-0000-0000-0000-000000000000"........xmlns:ns3="clr-namespace:BHOLD.Workflow.Activities;Assembly=BholdFimActivities, Version=5.0.1992.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
3.       <ns0:ApprovalActivity  ......>
4.              <ns2:ReceiveActivity.WorkflowServiceAttributes>
5.                     <ns2:WorkflowServiceAttributesConfigurationName="Microsoft.ResourceManagement.Workflow.Activities.ApprovalActivity"Name="ApprovalActivity"/>
6.              </ns2:ReceiveActivity.WorkflowServiceAttributes>
7.       </ns0:ApprovalActivity>

Finally, create a request MPR with the following settings.
RequestorAll People
PermissionGrant Permissions is checked
Target Resource Definition Before RequestAll BHOLD_ROLE that starts with MyRole
Target Resource Definition After RequestAll BHOLD_ROLE that starts with MyRole
Resource AttributesbholdRequestItemId; Comment; Subject
AuthZ WorkflowThe one we just created

Next time someone requests a role that starts with "MyRole", FIM will ask approval from the requestor's manager.

Note: You can modify the out of the box workflows. When you do that, make sure the XOML has the BHOLD DLL referenced.

Final Remarks

You can configure approvals for BHOLD in so many different ways. The BHOLD way is discussed here Understanding the role-approval process in BHOLD FIM Integration. It is recommended to use this approach. The Non-BHOLD approach I'm demonstrating here is not a replacement, and I'm not trying to compare the two. FIM is a powerful platform and we can configure it in so many different ways. For example, I can add the manager's approval as an extra step for one of the default BHOLD approval workflows. This way I will end up with two level of approvals, which might meet some clients requirements.

I observed one limitation with BHOLD approvals. It is limited to three type of role approvals (Role Managers, Line Managers, and Security Officers). You can also combine different BHOLD role approvers in the same workflow. For example, your workflow can ask approval from the Line Managers, then ask approval from Role Managers. If your client needs more than three level of approvals, then you will end up short and you will have to find a different way to get your approvers.

A supervisor role is a special role in BHold. It allows users who have this role to view other BHold objects, and if given appropriate permissions, they can modify those objects. In this post, we are interested in two things:
  • How to allow a user with a supervisor role to manage other users' roles?
  • How to allow a user to delegate his supervisor role?
For more information about supervisor role, please visit the following link

Creating a Supervisor Role

When installing BHold Core, a default supervisor role will be created, and linked to all Organizational Units.  You can also create your own supervisor role/s depending on your implementation. The link above has some recommendations from Microsoft regarding Supervisor Roles.
To create supervisor role, you need to login to BHold Core Components, and follow the following steps:
  1. On the left hand side, click on Roles
  2. Click on Add
  1. Fill in the Description, and check the box for supervisor role
As I have mentioned earlier, the default supervisor role can manage all objects, therefore by default it will be linked to this object we are creating.
  1. Click OK

Linking Supervisor Roles to Organizational Units

We would like to allow Ellen (our test user) to manage other users. Right now, using the self-service portal, she can only request roles for herself and view her own roles.

Below are the steps you can take to allow Ellen to manage other users' roles:
  1. Create a new OU under the root "MySupervisorOU"
  1. After the OU has been created, expand Roles, and click Modify
  1. Search for, and add "MyFirstSupervisor" to "MySupervisorOU"
  1. Click Add to proceed
  1. Expand Users, and click Modify to Add Ellen to this OU, which will automatically give her "MyFirstSupervisor"
  1. Lets select the OU/s "MyFirstSupervisor" will manage. For that, I created another OU, called "TheSupervisedOU" and I will add "MyFirstSupervisor" to it

Now, Ellen will see a new tab called "Manage Users", and she should be able to add/revoke roles for those users

Allow users to delegate their supervisor role

Delegation is basically assigning user's role to someone else to perform his/her job. In the example above, we linked "MyFirstSupervisor" to "MySupervisorOU" as an effective role, therefore, Ellen will not be able to delegate it.

For that, we will need to change the link between "MyFirstSupervisor" and "MySupervisorOU" to be proposed. We have to go back to step 3 and 4 above, remove "MyFirstSupervisor", and Add it again. However, this time we will choose it to be proposed.
After you click Add, you should be able to expand the roles, and activate it
 Now, Ellen should be able to go to the self-service portal and delegate the role to someone else. As a result, whoever she delegates the role to, should be able to add/revoke roles for those users in "TheSupervisedOU".

Recent Bloggers

  • Website This email address is being protected from spambots. You need JavaScript enabled to view it.
  • This email address is being protected from spambots. You need JavaScript enabled to view it.
  • This email address is being protected from spambots. You need JavaScript enabled to view it.
  • This email address is being protected from spambots. You need JavaScript enabled to view it.
  • This email address is being protected from spambots. You need JavaScript enabled to view it.

User Login