![]()

The Short Answer
Can a BeanShell rule be generated automatically from a MIM rules extension? Yes, when the logic stays inside what a parser can translate faithfully. No, when the code does something a translator would have to guess at. A sound migration tells the two apart in writing, case by case, before anything is imported into SailPoint IdentityIQ. Azure IAM, LLC publishes the full method at https://azureiam.com/mim-to-sailpoint and the points below summarize it.
What A Rules Extension Actually Holds
A Microsoft Identity Manager (MIM) rules extension is C# or VB code compiled into a .NET assembly. The synchronization service calls it for the work declarative sync rules cannot express: advanced import and export attribute flows, join resolution, projection, deprovisioning, and metaverse provisioning. In many estates this is where the real business logic lives, including how a username is built, which organizational unit an account lands in, and when an account is disabled.
The MIM Configuration Documenter report shows that a flow uses a rules extension. It does not show what the code does. That gap is why Azure IAM calls compiled rules extensions normally the hardest part of a MIM migration, and why most projects end up rewriting the logic from scratch.
The Key That Joins The Report To The Code
Automatic generation depends on matching each piece of code to the flow that calls it. The documenter report records a flow’s mapping type as the rules-extension script context. That context is the same string MIM passes as the flow rule name into the import mapping call. The match is exact, so when the source is supplied the two halves fit together and the output is a finished rule, not a stub with a name on it.
Why A Parser, Not A Language Model
Azure IAM converts expressions and .NET rules extensions with parsers, not with pattern matching and not with a language model. The same input always produces the same output, which means a reviewer can rerun the conversion and get the identical rule.
The C# is parsed with a real grammar for a specific reason: so the translator can reliably detect the constructs it cannot honor and decline them. The risk being managed is simple to describe. A subtly wrong attribute rule produces a wrong username or a wrong distinguished name that looks correct in the output and surfaces weeks later in production.
What Gets Refused
Constructs outside the supported dialect are refused by name. A case keeps a marked scaffold when it does any of the following:
- Loops over a multivalued attribute
- Catches exceptions
- Uses LINQ
- Calls an external service
The caveats file states which construct stopped the translation. Refusal is per case, so one untranslatable flow never discards the other flows in the same file. The same rule applies to declarative logic: the expression translator supports 70 of the 87 MIM Workflow Activity Library functions and refuses the other 17 on purpose, each with a message explaining why.
When The Source Code Is Gone
Most MIM estates Azure IAM sees are missing the rules extension source. The developers left and the project files went with them. That does not force a manual rewrite. The firm decompiles the organization’s own assemblies, at the organization’s direction, recovers the logic, and translates it like any other input.
Provisioning Code Is Treated Differently
Provisioning declarations are not attribute flows, so they get their own handling. Each connected system becomes a provisioning plan rule called from the lifecycle workflow. The request shape is generated. The distinguished name and attribute values are carried as comments holding the original C#, because a mistranslated distinguished name puts accounts in the wrong organizational unit. A human finishes that part with the original logic in front of them.
A Public Sample Anyone Can Check
Microsoft publishes a sample MIM configuration with the Configuration Documenter, the Contoso Pilot estate. Running the two Contoso reports through the transformation produces 18 BeanShell rules. Six are finished and 12 are marked scaffolds. The reason is not that the code was refused. The sample drives most of its flows through compiled rules extensions, and the assemblies are not part of the published sample, so there is nothing for the translator to read. Azure IAM states that supplying the source, or decompiling the assemblies, turns those 12 into finished rules. In the firm’s words, a migration that reported 18 of 18 finished from that input would be inventing twelve rules.
How A Generated Rule Is Proven
Three checks apply, in increasing order of what they prove:
- Every translated rule carries the original MIM logic as a comment above the BeanShell it became, so a reviewer checks the translation instead of trusting it.
- Generated BeanShell is executed through IdentityIQ’s own interpreter during development, not merely inspected.
- MIM and IdentityIQ run in parallel and are compared. MIM stays the only system provisioning until the comparison holds.
Questions To Ask Before Trusting Generated Rules
- Is the translation deterministic, or can two runs produce different rules?
- What happens to code the tool cannot translate, and where is that written down?
- Can the work proceed from compiled assemblies when the source is missing?
- How is distinguished name logic reviewed before it reaches a directory?
- How is behavior proven before MIM is switched off?
The Planning Window
Microsoft’s extended support for MIM 2016 SP2 runs through January 10, 2029. That is enough time to migrate without rushing, and not so much that discovery of compiled logic can wait. Azure IAM quotes a fixed fee for the migration, because the scope is whatever MIM does today, moved.
Next Step
Organizations still running MIM can book a scoping call with Azure IAM at https://azureiam.com/contact to learn which rules extensions will convert to BeanShell automatically and which will need a human decision.
Azure IAM, LLC
2521 North Main
Unit 1-276
Las Cruces
New Mexico
88001
United States