Microsoft late last year introduced the ‘MIMWAL’, or to say it in full: (inhales) ‘Microsoft Identity Manager Workflow Activity Library’ – an open source project that extends the default workflows & functions that come with MIM.
Personally I’ve been using a version of MIMWAL for a number of years, as have my colleagues, in working on MIM projects with Microsoft Consulting. This is the first time however it’s been available publicly to all MIM customers, so I thought it’d be a good idea to introduce how to source it, install it and work with it.
Microsoft (I believe for legal reasons) don’t host a compiled version of MIMWAL, instead host the source code on GitHub for customers to source, compile and potentially extend. The front page to Microsoft’s MIMWAL GitHub library can be found here: http://microsoft.github.io/MIMWAL/
Compile and Deploy
Now, the official deployment page is fine (github) but I personally found Matthew’s blog to be an excellent process to use (ithinkthereforeidam.com). Ordinarily, when it comes to installing complex software, I usually combine multiple public and private sources and write my own process but this blog is so well done I couldn’t fault it.
…however, some minor notes and comments about the overall process:
- I found that I needed to copy the gacutil.exe and sn.exe utilities you extract from the old FIM patch in the ‘Solution Output’ folder. The process mentions they need to be in the ‘src\Scripts’ (Step 6), but they need to be in the ‘Solution Output’ folder as well, which you can see in the last screenshot of that Explorer folder in Step 8 (of process: Configure Build/Developer Computer).
- I found the slowest tasks in the entire process was sourcing and installing Visual Studio, and extracting the required FIM files from the patch download. I’d suggest keeping a saved Windows Server VM somewhere once you’ve completed these tasks so you don’t have to repeat them in case you want to compile the latest version of MIMWAL in the future (preferably with MIM installed so you can perform the verification as well).
- Be sure to download the ‘AMD 64’ version of the FIM patch file if you’re installing MIMWAL onto a Windows Server 64-bit O/S (which pretty much everyone is). I had forgotten that old 64 bit patches used to be titled after the AMD 64-bit chipset, and I instead wasted time looking for the newer ‘x64’ title of the patch which doesn’t exist for this FIM patch.
‘Bread and Butter’ MIMWAL Workflows
I’ll go through two examples of MIMWAL based Action Workflows here that I use for almost every FIM/MIM implementation.
These action workflows have been part of previous versions of the Workflow Activity Library, and you can find them in the MIMWAL Action Workflow templates:
- MIMWAL: Update Resource https://github.com/Microsoft/MIMWAL/wiki/Update-Resources-Activity
- MIMWAL: Generate Unique Value https://github.com/Microsoft/MIMWAL/wiki/Generate-Unique-Value-Activity
I’ll now run through real world examples in using both Workflow templates.
Update Resource Workflow
The Update Resource MIMWAL action workflow I use all the time to link two different objects together – many times linking a user object with a new and custom ‘location’ object.
For new users, I execute this MIMWAL workflow when a user first ‘Transitions In’ to a Set whose dynamic membership is “User has Location Code”.
For users changing location, I also execute this workflow use a Request-based MPR of the Synchronization Engine changing the “Location Code” for a user.
This workflow looks like the following:
The XPath Filter is: /Location[LocationCode = ‘[//Target/LocationCode]’]
When you target the Workflow at the User object, it will use the Location Code stored in the User object to find the equivalent Location object and store it in a temporary ‘Query’ object (referenced by calling [//Queries]):
The full value expression used above, for example, sending the value of the ‘City’ attribute stored in the Location object into the User object is:
This custom expression determines if there is a value stored in the ‘[//Queries]’ object (ie. a copy of the Location object found early in the query), and if there is a value, then send it to the City attribute of the user object ie. the ‘target’ of the Workflow. If there is no value, it will send a ‘null’ value to wipe out the existing value (in case a user changes location, but the new location doesn’t have a value for one of the attributes).
It is also a good idea (not seen in this example) to send the Location’s Location Code to the User object and store it in a ‘Reference’ attribute (‘LocationReference’). That way in future, you can directly access the Location object attributes via the User object using an example XPath: [//Person/LocationReference/City].
Generate Unique Value from AD (e.g. for sAMAccountName, CN, mailnickname)
I’ve previously worked in complex Active Directory and Exchange environments, where there can often be a lot of conflict when it comes to the following attributes:
- sAMAccountName (used progressively less and less these days)
- User Principal Name (used progressively more and more these days, although communicated to the end user as ’email address’)
- CN (or ‘container’ value, which forms part of the LDAP Distinguished Name (DN) value. Side note: the most commonly mistaken attribute for admins who think this is the ‘Display Name’ when they view it in AD Users & Computers.
- Mailnickname (used by some Exchange environments to generate a primary SMTP address or ‘mail’ attribute values)
All AD environments require a unique sAMAccountName (otherwise you’ll get a MIM export error into AD if there’s already an account with it) for any AD account to be created. It will also require a unique CN value in the same OU as other objects, otherwise the object cannot be created. Unique CN values are generally required to be unique if you export all user accounts for a large organization to the same OU where there is a greater chance for a conflict happening.
UPNs are generally unique if you copy a person’s email address, but sometimes not – sometimes it’s best to combine a unique mailnickname, append a suffix and send that value to the UPN value. Again, it depends on the structure and naming of your AD, and the applications that integrate with it (Exchange, Office 365 etc.).
Note: the default MIMWAL Generate Unique Value template assumes the FIM Service account has the permissions required to perform LDAP lookups against the LDAP path you specify. There are ways to enhance the MIMWAL to add in an authentication username/password field in case there is an ‘air gap’ between the FIM server’s joined domain and the target AD you’re querying (a future blog post).
In this example in using the ‘Generate Unique Value’ MIMWAL workflow, I tend to execute as part of a multi-step workflow, such as the one below (Step 2 of 3):
I use the workflow to generate a query of the LDAP to look for existing accounts, and then send that value to the [//Workflowdata/AccountName] attribute.
The LDAP filter used in this example looks at all existing sAMAccountNames across the entire domain to look for an existing account: (&(objectClass=user)(objectCategory=person)(sAMAccountName=[//Value]))
The workflow will also query the FIM Service database for existing user accounts (that may not have been provisioned yet to AD) using the XPath filter: /Person[AccountName = ‘[//Value]’]
The Uniqueness Key Seed in this example is ‘2’, which essentially means that if you cannot resolve a conflict with using other attribute values (such as a user’s middle name, or using more letters of a first or last name) then you can use this ‘seed’ number to break the conflict as a last resort. This number increments by 1 for each confict, so if there’s a ‘michael.pearn’, and a ‘michael.pearn2’ for example, the next one to test will be ‘michael.pearn3’ etc etc.
The second half of the workflow shows the rules to use to generate sAMAccountName values, and the rules in order in which to break the conflict. In this example (which is a very simple example), I use an employee’s ‘ID number’ to generate an AD account. If there is already an account for that ID number, then this workflow will generate a new account with the string ‘-2’ added to the end of it:
Value Expression 1 (highest priority): NormalizeString([//Target/EmployeeID])
Value Expression 2 (lowest priority): NormalizeString([//Target/EmployeeID] + “-” + [//UniquenessKey])
NOTE: The function ‘NormalizeString’ is a new MIMWAL function that is also used to strip out any diacritics character out. More information can be found here: https://github.com/Microsoft/MIMWAL/wiki/NormalizeString-Function
Microsoft have posted other examples of Value Expressions to use that you could follow here: https://github.com/Microsoft/MIMWAL/wiki/Generate-Unique-Value-Activity
My preference is to use as many value expressions as you can to break the conflict before having to use the uniqueness key. Note: the sAMAccountName has a default 20 character limit, so often the ‘left’ function is used to trim the number of characters you take from a person’s name e.g. ‘left 8 characters’ of a person’s first name, combined with ‘left 11 characters’ of a person’s last name (and not forgetting to save a character for the seed value deadlock breaker!).
Once the Workflow step is executed, I then send the value to the AD Sync Rule (using [//WorkflowData/AccountName] to then pass to the outbound ‘AccountName –> sAMAccountName’ outbound AD rule flow:
More ideas for using MIMWAL
In my research on MIMWAL, I’ve found some very useful links to sample complex workflow chains that use the MIMWAL ‘building block’ action workflows and combine them to do complex tasks.
Some of those ideas can be found here by some of Microsoft’s own MSDN: https://blogs.msdn.microsoft.com/connector_space/2016/01/15/the-mimwal-custom-workflow-activity-library/
- Create Employee IDs
- Create Home Directories
- Create Admin Accounts
I particularly like the idea of using the ‘Create Employee ID’ example workflow, something that I’ve only previously done outside of FIM/MIM, for example with a SQL Trigger that updates a SQL database with a unique number.