Active Directory is NOT an IdM Technology (without #MIM2016 or similar)

It continues to frustrate me that publications such as this recent white paper from the Microsoft EMS (Enterprise Mobility and Security) team still underplay the need for organisations to get their on-premises identity management under control before turning on AAD Connect.  Statements like the following:

  • “… our organizations have long used on-premises identity management technologies such as Microsoft Active Directory”
  • ” Your users’ identities can still come from your own directory service—you’re still in control …”

seem to imply that of course you control your own AD today.  Last I heard AD was an identity technology, but an identity management technology???  Can anyone really be in control of their on-premises directory service without some form of identity life-cycle management in place beyond the ADUC console itself?

Fellow Adelaide MVP Adam Fowler pointed me at a product called Softerra Adaxes, and explained how he is using this to centralise his business rules for managing identity lifecycles – but directly to AD via a nifty browser-hosted web application.  This adds the missing “smarts” (as he likes to call them) that are missing natively from the AD platform.  On a small scale, with only a few hundred employees, Adam is able to ensure that only people in his organisation with current access entitlements are able to authenticate to his systems, and securely access resources on his company’s network.  I would still like to see him wire up his company’s HR system as a source of truth (SoT) for not only employee identity data, but also joiner/mover/leaver events.  That said, the checks and balances he puts in place enforce ongoing compliance, if not quite the continuous compliance I can achieve with say a MIM2016 implementation.  If only every SMB had someone like Adam taking care of things – but what of the rest?

In my role as IAM solution architect and implementer over the last decade, working predominantly with Microsoft Identity Manager (and its various predecessors), I have come to appreciate that what we now refer to as “on-premises” IAM solutions are starting to lose their appeal.  Yet don’t be fooled!  Just because you might choose to run your IAM platform either wholly or in part from a cloud platform such as OKTA or SailPoint, the Microsoft “Hybrid Identity” model (supported by AAD Connect) is still very much dependent on the integrity being enforced first and foremost in your on-premises directory, which for the most part continues to be Microsoft AD.

You may have heard about HR-driven identity management in Azure with WorkDay, whereby AAD accounts are provisioned directly from a WorkDay feed.  But what you might not know is that this does not work in a hybrid scenario – whereby a “thin agent” is required to provision to the on-premises AD first, from where AAD Connect kicks in and provisions to AAD.  This remains the ONLY supported hybrid model today for not only WorkDay but every HR-driven scenario … you have to manage the on-premises directory first.

For all those organisations who have invested in an on-premises IDM solution, announcements like the Azure AD and SailPoint collaboration this week should only reinforce how fortuitous it is that you are now in a position to reap the rewards of doing so. Some might try to tell you that you are now being left behind on a legacy platform, but why “throw out the baby with the bathwater”?  With Microsoft’s investment in what happens downstream of your AD (either directly or via AAD Connect when via the cloud), you can continue leverage your existing investment that puts you “in control of your own directory services”.  The only thing you now should consider is whether or not to extend that platform in a downstream sense to do something that now makes more sense in the cloud.

For those organisations which have NOT yet made such an investment, you are now in a better position than ever to make up on lost ground:

  • Microsoft now grants free use of the MIM2016 synchronisation service with a Windows Server platform license, reducing the capital outlay on a traditional on-premises solution for the larger more complex enterprises who want to leverage what remains Microsoft’s endorsed on-premises IAM platform;
  • UNIFY provides an SaaS option for the SMBs who want to harness the power of an enterprise grade solution for a fraction of the cost, or instead you may want to consider the Adaxes style approach; and
  • OKTA, SailPoint and others provide complete IAM lifecycle solutions hosted in the cloud.
Posted in Active Directory, Azure Active Directory, MIM (Microsoft Identity Manager) 2016 | 1 Comment

Your #MIM2016 or #FIM2010 Starter Pack

With all the excitement this week of the announcement of the Azure AD and SailPoint collaboration, it got me thinking about how the Microsoft IAM landscape is continuing to evolve both on premises and in the Microsoft cloud.  The message has always been very clear – use MIM for traditional identity life-cycle provisioning (joiners) and sync (movers/leavers) to AD, and use AAD Connect as the identity bridge between AD and your AAD tenant.  Nothing has really changed in this specific regard – rather we now have some significant post-account provisioning technology to leverage for access management, which to be fair has been rather lacking for some time.

For me this is a god-send for those who might still be looking for business justification to invest in an IdM solution based on MIM 2016, typically driving identity life-cycle from a suitable authoritative source such as a modern HR system (one that is always up to date and a great source of change events).  Why?  Because unless you’re reeling in the wake of a security breach and have no choice but to attain compliance over your identity store, the benefits in terms of $$$ savings through improvements in identity provisioning efficiency often don’t seem to resonate loud enough with those holding the corporate purse strings.  However, when you combine this with features such as Azure Advanced Threat Analytics, automated AAD provisioning to cloud apps such as Salesforce, and now advanced identity governance across your on-premises and cloud resources with SailPoint, the value-add of a sound MIM 2016 platform starts to shine through.

So with this in mind, I expect more people without any MIM or FIM experience will be turning their attention to what they can do right now to leverage the rapidly growing list of benefits, and for my money this has always been a simple HR-driven Synchronization solution for joiners, movers and leavers.  Get this right and everything else flows on from this.

So I guess most people would start with the following MS links:

… but where would they go from here?

Given that’s not so clear, I thought I would share my own quick Starter Pack for people new to this piece of Microsoft kit which has been part of the fold since basically the beginning of the millennium.  Hope you find this one as useful as others have done.  Although references are mostly to FIM 2010, they apply equally to MIM 2016 (or ILM and MIIS before that).

Since putting this together I’ve become aware of this WIKI article on the same subject, but I wanted to share my own list nonetheless.  Let me know in the comments if you feel I have left out anything significant.  At some stage I will probably remove the section below and update the WIKI, but for now, enjoy.


 

 

Synchronization in Forefront Identity Manager 2010

fimsync

This is a VERY short introductory online video – 3 minutes 44 seconds

“About This Video: The ability to manage distributed identity information from a central point is key component of the Microsoft Forefront Identity Manager (FIM) 2010 architecture. This process is governed by a well-defined and customizable set of synchronization rules. This video introduces you to the central concepts of inbound and outbound synchronization in FIM.”

For more information see

Note: the second 2 topics are linked from the first.

 

Run Profiles in FIM 2010 R2

This is a short technical article on a fundamental concept our solution uses continually every 2 hourly sync cycle.

 

“Run profiles specify the parameters with which a management agent is run in Microsoft® Forefront® Identity Manager (FIM) 2010 R2. You can create one or multiple run profiles for a management agent. Further, each profile consists of one or more steps. By combining steps in a profile, you can more accurately control how your data is processed.”

 

 

FIM “Ramp Up” training – Implementing Forefront Identity Manager 2010

This is an archive old FIM 2010 training material, some of which is no longer available.  At one stage there was a Microsoft TechNet online resource comprising 3 modules that are essential understanding any synchronization solution.  While it has been mostly superseded, I still find this material very useful.
Note: – the first module is only 1 hour and should be watched only after watching the above video and reading the above 3 articles.

“This course introduces and explains the features and capabilities of Microsoft Forefront Identity Manager 2010 (FIM), and provides an overview of the solution scenarios that FIM addresses. The course format includes presentation, discussion, demonstration, and many hands-on exercises. It is intended for students who have no previous Forefront Identity Manager 2010 or Microsoft Identity Lifecycle Manager 2007 (ILM) experience.

After completing this course, students will be able to:
· Understand FIM concepts and components.
· Identify appropriate FIM scenarios.
· Manage users, groups, and passwords using FIM.
· Synchronize identity data across systems, such as Active Directory and HR.
· Understand the issues involved in loading data (initial load, backup, and disaster recovery).
· Configure security for different levels of user.
· Manage password self-service reset and synchronization.
· Automate run cycles.
· Handle sets, simple workflows, and management policy rules (MPRs).”

Although the virtual labs are not available for modules #1 or #2, the article (PDF) and video (WMV) can still be downloaded and should be watched/followed to achieve the level of understanding you will need.

 

Test Lab Guide: Installing Forefront Identity Manager 2010 Synchronization Service

This guide contains instructions for setting up the Forefront Identity Manager 2010 Synchronization Service in a test lab based one new server computer, two preexisting server computers, and one preexisting client computer. The resulting Forefront Identity Manager 2010 Synchronization Service test lab demonstrates and verifies installation. This test lab guide is a smaller modified version of the Forefront Identity Manager 2010 test lab guide. This test lab guide is being provided for situations where a full installation of Forefront Identity Manager 2010 is not required. This test lab guide does not cover installing the Forefront Identity Manager 2010 portal or any of the features that require a full installation of Forefront Identity Manager 2010. This guide should only be used when only the Forefront Identity Manager 2010 Synchronization Service is required.

Other Reading

 

Posted in FIM (ForeFront Identity Manager) 2010, ILM (Identity Lifecycle Manager) 2007, MIM (Microsoft Identity Manager) 2016, Uncategorized | Leave a comment

Azure EMS Conditional Access and Enterprise IAM

This week part 2 of a series of blog posts on implementing Azure EMS Conditional Access (CA – part 1 here) was published on Microsoft’s Enterprise Mobility and Security Blog.

Predictably, perhaps, this got me thinking about what I might need to have in place before being able to implement this for one of my customers.  From the part 1 post I can see that I need the following “conditions”:

  1. User group
  2. Location (IP range)
  3. Device state
  4. Risk

Being an IAM guy myself, my attention was drawn immediately to the first 2 items, purely on the basis that I can’t influence #3 (function of the device and presumably the Intune or equivalent setup), and #4 is data maintained within this Azure feature at the discretion of the Enterprise (to confirm).  Of course #2 is purely about matching IP addresses to trusted network locations, so let’s just look at #1.

User group (integrity thereof)

In an Azure context, this means an Azure AD (AAD) group(s) can be used to apply rules to specific users.  However, who manages these groups, and how?  If you are using AAD Premium then groups can be defined dynamically, thereby giving the impression that we can avoid the need to maintain membership ourselves.  Of course not all groups are going to be manageable this way (e.g. group membership needs to be controlled by a group owner), but assuming you have a group which can be (e.g. “all Adelaide Office managers”), and assuming EMS Conditional Access supports dynamic groups (TBC) then we could automatically grant access to some sort of restricted application in this manner.  However, how confident can we be in the data integrity of the attributes (in this case manager and location)?  Can we be sure that every manager in Adelaide is accurately identified by these properties in AAD?

If it happens we are considering a hybrid identity context, then this could instead be a group synchronised with an on-premises group mastered in Active Directory (AD), or even better some form of IAM platform such as MIM 2016.  In this way (using MIM as an example) it is possible to improve things significantly, e.g.

  • Ensure both manager and location attributes are sourced and (MIM-)synchronised from a single reliable/authoritative source such as an HR system, where data is always maintained (hopefuly) in a timely fashion
  • Master the group definition in the MIM portal, either as a static group (e.g. with membership approval workflows) or a dynamic (query based) group based on our 2 attributes – you can even have MIM auto-generate these groups for you if you wish (see part 3 of Tomasz’ presentation to the MIMTeam User Group here)
  • Be sure to configure AAD Connect to sync the AD users and groups (complete with full attribute set) to AAD

As with previous posts about platform features which leverage user metadata, such as AD Dynamic access, the importance of ensuring and enforcing the integrity of that metadata through the use of a sound Enterprise IAM implementation cannot be overstated.  Sure Azure EMS Conditional Access depends only on groups existing in order to be enforced – but don’t expect this to be effective if the group integrity itself is questionable.

Microsoft Ignite 2017, Australia

For those in my part of the world, don’t forget to register for this year’s event from 14-17 February.  If you are one of the first 20 to register with the code K6EZIUB2, you will pay only $1500.  However, act now, as discounted registrations are only available until 10 February 2017.

Posted in Azure Active Directory, FIM (ForeFront Identity Manager) 2010, MIM (Microsoft Identity Manager) 2016 | Leave a comment

#AADConnect exception: 0x80230306 (The dimage has an anchor that is different than the image.)

I’ve been working in a lab lately where I’ve been running into the above problem using AAD Connect’s Staging Mode.  We’re at a point where we’re looking to swap out an existing custom FIM 2010 R2 solution (with the soon-to-be deprecated WAAD connector) for the more mainstream solution recommended today by Microsoft for a multi-forest-single-tenant configuration.

I didn’t find the error message (detailed below) all that helpful, and although I did recall seeing it in a FIM context a long time ago, it turns out that the cause (in my case at least) was not something that you would deduce from the above in a million years :).  I am including the following for future reference when others might run into the same problem – and as in medicine you shouldn’t assume every symptom that looks the same has the same root cause.  However, just like with Doctor Google, I am going to give you my remedy and let you discover the truth for yourself if and when you run into this yourself.

Symptoms

The problem is distinguishable by

  • Inbound sync failing with the following:
Unable to persist entry. 
 An error occurred, ..\ObjectNamespace.cpp(636), code 80230306, 
 BAIL: MMS(3160): ..\tower.cpp(10789): 0x80230306 (The dimage has an anchor that is different than the image.)
  • An explicit AAD disconnector (i.e. a pending export delete) exists for the matching source anchor of the above object in error
  • No AAD connector is joined to the metaverse object for which the error is produced
  • cloudFiltered = true (metaverse attribute value)

Cause

To reproduce the circumstances that generated this problem:

  • The solution MUST be in STAGING MODE (prevents actual export to AAD)
  • There must be an object already in the tenant matching the source anchor of an AD object which is IN SCOPE of AADConnect. In my case for an object to exhibit this error it had to meet the following criteria:
    • Must have EA12 set
    • Must be in an in-scope OU
    • Must NOT be filtered from sync
      • LAB: Must be in the corresponding “filter groups” (i.e. specified regional +/or CORP groups)
      • LAB and PROD: no other form of filter can be in place (custom sync rule)

The following sequence of steps was found to consistently reproduce the problem:

  • Move the object out of scope of AADConnect (in our case taking it out of the corresponding filter groups achieved this, but we could also have moved it out of scope of the selected OU)
  • Allow delta import and delta sync to run – which triggers a disconnect (pending export DELETE)
  • Allow the AAD MA delta delta sync cycle to run (IMPORTANT: this puts the AAD CS object into an EXPLICIT DISCONNECTOR state – noting that in STAGING mode the export is/can never applied to AAD)
  • Move the object back into scope of AADConnect (add back into filter group(s))
  • Allow delta import and delta sync to run – which SHOULD trigger a re-provision to AAD (pending export ADD) – but instead we get the above BAIL error.

Online investigation

Old TechNet Instructions existed for DirSync in the past with errors similar to this, but did not resolve the problem (full import/sync did not clear the problem because it was not OU related).

Other reported issues similar to the above both here and here.

Resolution

To resolve the problem there are at least 3 options:

  • Full reinstall (the experience of some with this problem in the past – as with the above 2 links) – not what most would find acceptable in PROD
  • Delete the AAD CS (possible – this is what I ended up doing today – after confirming we had this problem)
  • Delete the AAD object and run a DI/DS to delete the AAD CS “explicit disconnector” object

Explanation (using MIIS/ILM/FIM/MIM sync principles):

  • Once an object is in an EXPLICIT DISCONNECTOR state it can only be cleared in one of the following ways:
    • It is allowed to be exported to AAD (i.e. the delete performed) – not possible in STAGING MODE
    • It is deleted in the tenant directly (Remove-MSOLUser PowerShell commandlet) – not desirable if the object has permissions etc. you wish to retain
    • It is commuted from an “explicit disconnector” to a “normal disconnector” – possible in FIM/MIM but not supported in AADConnect
    • The entire CS is deleted – cost of 1-2 hours delete/import/full sync (AAD connector only)
    • The entire Config is deleted and recreated – for me this came at the cost of approx 3 hours config and 5 hours full sync (all 6 connectors)
  • While an explicit disconnector is present for an object matching the same sourceAnchor, any object exhibiting the above BAIL error will continue to do so until it is taken out of scope of AADConnect

Footnote

The outcome of the above is that we need to recognise and avoid the circumstances that lead to the above condition while in STAGING MODE – however this may be unavoidable in PROD during say a pre-go-live phase.  As such these BAIL errors are entirely possible, especially with delete/adds happening in parallel with your existing FIM solution that you are about to swap out, and which has no concept of a “staging mode”.

Whenever this occurs in future a CS full delete/reload will most likely be required to resolve the problem – unless Microsoft can provide a means of targeting the disconnectors individually in the AAD CS and allow their conversion from EXPLICIT to NORMAL disconnector. However this is unlikely in the short term.

Posted in Azure Active Directory, Azure AD Connect Sync | Tagged , , | 2 Comments

Managing Identities in a Hybrid World

Last Tuesday I had the pleasure of addressing a combined audience of fellow local MVP Pete Calvert‘s Adelaide Windows User Group and the Adelaide System Center User Community.  So I thought I’d post the identitygovernancefor-o365 deck from that meeting here, mainly for the benefit of those in the two groups.

Coincidentally, this same week my colleague Shane Day from my company UNIFY’s leadership group posted this article on the topic of the Top 3 Identity Management tips for Frontier Software chris21 users which I thought nicely reinforces the ideas that were discussed at on Tuesday – which (happily) went way overtime with a very engaged group of IT folks.

The angle of my presentation was simply directed to those presiding over a hybrid AD/AAD identity base (hopefully using Microsoft AAD Connect to do so) in order for their workforce to access Office 365 licensed applications like SharePoint, Exchange Online and Yammer.   They may also be using federation to provide SSO to other cloud applications like SalesForce.

For any such organisation,  improving governance around not only who can logon to your company network, but who has access to what at any given time, should be an ever increasing priority.  In my experience your HR platform is not only the best source of accurate employee identity information, but also the best source of  the key events which can be harnessed to apply access-related changes to your user identity records – think “joiners, movers and leavers” .

This is not a new concept by any means, but when you look at this in a hybrid identity context you can start to see there really is no limit to the potential of harnessing the HR source to drive downstream application access.  Combine this with the workflow capabilities of in identity and access management (IAM) platform such as MIM2016 (the sync engine of which now comes free with your Enterprise Windows Server licenses) and you can start to realize additional automation benefits by combining request with role-based access – such as the assigning of Office 365 licenses based on group membership (see my previous post on how to use AzMan on premises for this).

For those who happen to use chris21 (or perhaps Aurion) HR platform but are not yet ready to take the plunge and build a full scale IAM solution, there is good news for you too!   UNIFY has both on premises or cloud (SAAS) offerings that simply allow you to harness your HR system to simply drive your on premises AD, which in turn will drive your AAD via AAD Connect.  If this is you I strongly encourage you take a look to find out more.

Posted in Azure AD Connect Sync, Event Broker for FIM 2010, Identity Broker LITE, MIM (Microsoft Identity Manager) 2016 | Leave a comment

#AADConnect sync: The Inbound sync rules in scope have different join criteria.

I’ve finally had the opportunity to work with AAD Connect over these past weeks, and its been one of those “everything old is new again” experiences.  It’s one thing to hear the architectural objectives that Andreas talked about for the Azure “identity bridge” product that was to replace AADSync, and DirSync before it – but it’s only when you get your hands dirty for the first time that you really start to understand what exactly that means.  In my case I am replacing a custom FIM 2010 multi-forest sync implementation with a custom AADConnect solution.  FIM had previously replaced DirSync before it, and while I am finding that it hasn’t quite been the plain sailing I was hoping for, I remain confident I will get there based on alignment to one of the listed topology models.

In my target environment I have something close to the “Multiple Forests – Account-Resource Forest” scenario, with FIM 2010 currently in place providing the identity bridge. However there are some key differences too, the main one being that the FIM instance I am replacing has only a single management agent to the resource forest, with no connectors to any of the regional forests.  This is made possible by a secondary FIM sync instance populating a bunch of extension attributes in the resource forest with feeds from each of the 5 AD regional forests, including the all-important immutableId.

Long story short … in the process of adjusting the OOTB sync rule solution for a multi-forest configuration, I have found myself

  1. disabling a bunch of sync rules (all up there were 195!);
  2. provisioning from the resource forest only (or “projecting” as we would say in MIM-speak) for each object type by changing the link type “provision” to “join” for all the regional connectors;
  3. changing the join rules for contacts and groups to only join on the immutableId extension attribute; and
  4. using AD groups to filter my pilot environment to reduce the sync analysis to a small managebale set of users, groups and contacts.

Now I am still to decide on whether or not point #3 is the way to go, but in the process of running the initial load sync step after changing all the contact and group rules with names that ended in “join”, I ran into this rather confusing error:

The Inbound sync rules in scope have different join criteria. Join Criteria:[objectGUID=sourceAnchorBinary CS=False], [extensionAttributeXX=extensionAttributeXX CS=False] Sync Rules: In from AD - Group Filtering[<guid>], In from AD - Group Join[<guid>]
 at Microsoft.MetadirectoryServices.SyncRulesEngine.JoinModule.ValidateAllApplicableSyncRules(IEnumerable`1 applicableSyncRules)
 at Microsoft.MetadirectoryServices.SyncRulesEngine.JoinModule.Execute(PipelineArguments argsToProcess)
 at Microsoft.MetadirectoryServices.SyncRulesEngine.Server.SyncEngine.RunSyncPipeline(SyncRulePipelineArguments pipelineData, List`1 pipelineChain)
 at Microsoft.MetadirectoryServices.SyncRulesEngine.Server.SyncEngine.Synchronize(SynchronizationOperation operation, IObjectLinkGraph inputGraph)
 at ManagedSyncRulesEngine.Synchronize(ManagedSyncRulesEngine* , CCsObject* sourceCsObject, CMvObject* mvObject, SynchronizationOperation operation, Char** error)

Not only did I get this error, but it occurred 5000 times and then stopped the sync run profile having reached the built-in error limit.  This kind of threw me because what I had read suggested that I had changed all of the OOTB join rules for contacts and users by observing the naming standards.  Yet there was obviously at least one rule I had missed – maybe more.  What was concerning me at the time was that maybe I had broken something by making the change that could not be recovered.  Thankfully the details I needed to identify the problem were in the details of the message … specifically that there was another sync rule which included a JOIN but which did not have a name which ended in “Join”.

It turned out that because of my use of group filters (item #4 in my list above), there were additional sync rules with a name ending in “Filtering” which also included a join statement – and these were still configured NOT to use my extension attribute.

 

So the remedy was simple – changing all the “Filtering” sync rules in addition to the “Join” rules, followed by a rerun of the initial load, was all that was required to restore to a working state.

Posted in Azure Active Directory, Azure AD Connect Sync | 1 Comment

Managing Office 365 Licenses with #MIM2016 and #AzMan – Part 2

In my last post I introduced the concept of using Windows Authorisation Manager (AzMan) to manage the automation of Office 365 licenses.  In this post I will go into detail on how the solution hangs together.

Complementing AAD Connect with MIM 2016

The main components of my solution are as follows:

  • AADConnect (OOTB identity bridge between AD and AAD for user/group/contact sync)
  • MIM 2016 (to complement AADConnect)
  • AzMan (SQL database storage option)
  • 2 MIM 2016 management agents (e.g. PowerShell)
    • User License Entittlements (sync source for user.assignedLicenses)
    • User License Assignment (sync target for user.assignedLicenses)

As many of you will know, it is technically possible to extend AADConnect to include additional management agents and negate the need for MIM2016, however this was not my recommended approach for many reasons, including the following:

  • AADConnect extensions will invariably require extended Microsoft support over and above the standard AADConnect support options;
  • MIM2016 synchronisation remains a cost-effective option for any enterprise IAM architecture on the Microsoft platform; and
  • The MIM synchronisation configuration for this solution requires no rules extensions (only direct attribute flows)

Aside from the AzMan approach itself, the benefits of using the MIM 2016 sync engine (or FIM 2010 R2) in lieu of the traditional scripted approach should not be surprising for any of us, and include the following:

  • State based approach – provide ongoing reconciliation between expected (entitlements) and actual (assignments), avoiding the need for report-based options such as this one;
  • Timeliness of changes – delta sync cycles can be used to process only the changes since the last sync cycle;
  • Maintainability – maintaining a centralised authoritative source of rules/roles governing license entitlements ensures ongoing ease of-maintenance; and
  • Auditability – enforcing a centralised authoritative source of rules/roles governing license entitlements ensures license accountability and compliance.

AzMan.Licensing

Creating the AzMan Store

Setting up an AzMan instance itself is straight-forward given this is a standard feature maintainable via a simple Windows MMC snap-in.

While there are 3 options for hosting my AzMan store, I chose SQL over XML and AD – a decision made easier by the fact I could reuse a SQL alias I already had in place for my MIM Sync service.  For more information on the choice of store, see Managing Authorization Stores.

  • Click on the Authorization Manager node in the LHS tree view
    Az1
  • From the Action menu, select Options…
    Az2
  • Click on Developer mode
    Az3
  • From the Action menu, select New Authorization Store…
    Az4
  • Select the Microsoft SQL store type and Shema version 2.0, then paste the following string into the Store name:
    mssql://Driver={SQL Server};Server=MIM01;/AzManStore/O365.Licensing

    … and in the Description enter:

    Authorization store defining QBE O365 licensing entitlements.
    * role definitions = SKUs and disabled plans
    * task definitions = plans
    * role assignments = AD group memberships required to fulfill user license entitlements
    For more details, including a full list of indexed service plans (tasks) see https://technet.microsoft.com/en-us/library/dn771771.aspx

    Az5

  • Click OK
  • Check that the (initialized) Licensing store is correctly displayed as follows:
    Az6
  • Select the O365.Licensing node (store) and select New Application… from the Action menu, then enter the following details:
    • Name = O365
    • Description = Office 365 Licensing
    • Version = 2
      Az7
  • Click OK

Note: The AzMan store must remain in Developer mode from this point so that configuration can continue via the MMC snap-in UI.

Configuring the AzMan Store for Office 365 Licensing

Initially I chose to set up my AzMan store data manually via the MMC snap-in.  You may choose to do this too, but I chose to script this entirely in PowerShell to assist me in the deployment phase, as well as allow my customer to maintain the master data in the way they were more comfortable (initially at least) – yes in a Microsoft Excel Spreadsheet.

Set up Task Definitions

In my AzMan model a “task” represents a service plan, or specifically a “disabled plan”.  When an SKU is assigned to a user, service plans that are to be excluded for that user are listed as disabled plans.  To get a list of all possible disabled plans I have used the latest Service Plan table from this TechNet article to come up with the following:
az8

When entitlement details are extracted for FIM processing, both the Name and the Description (“Seq” index) are read, but only when it is associated to a role definition with at least one disabled plan.  Plans must always be extracted/listed in index order.

Set up Role Definitions

For my model a “role” represents an SKU and zero or more disabled plans.  How these are set up will most likely be specific to your enterprise’s unique requirements, but the following is an example of how this might look.  Note that the SKU name appears in the Description property – this is an important part of the data model because this SKU name must be able to be extracted for each (arbitrary but unique) role name.
Az9

The role definition for “Office 365 Enterprise E3 – no Exchange nor Skype” is highlighted because this best illustrates the concept of optional disabled plans.  Opening the properties dialog you can see this is managed like so:
az10

When entitlement details are extracted for FIM processing, the Description is all that is read from any group-assigned role, along with the Name and Description (Seq) of any associated disabled plans.

Set up Role Assignments

This is where the real power of the model comes into play.  By assigning 1 or many AD groups to the roles constructed above, a collection of groups and a constructed string in the following form can be constructed:

Format
SubscribedSku.skuPartNumber : ServicePlanInfo.servicePlanName ; ServicePlanInfo.servicePlanName ; ...
Plan name : disabled plan name ; disabled plan name ; ...
Example
ENTERPRISEPACK:OFFICESUBSCRIPTION;SHAREPOINTENTERPRISE;EXCHANGE_S_STANDARD

The following is a dummy role assignment to illustrate the concept – but this screen would normally have at least one entry per defined role, and multiple AD groups assigned to each:
Az11
Az12

Bringing it all together

The following PowerShell script takes whatever data you have in the above store and renders it in the following table format:

  • groupDN
    Single value string property, retrieved from AD from the group ID read from the AzMan role assignment, this is then able to be joined on the user.memberOf DN
  • assignedLicenses
    Multi-value string property, constructed from the role and task data linked to the role assignment – this is the data which can be directly synchronised to Azure via the GRAPH REST API.

Note that the script makes use of the “MIM” SQL alias I already have set up for my MIM SQL connection – allowing me to host the script on the MIM synchronisation host server.

# -- BEGIN PowerShell Connector Script

 # Create the AzAuthorizationStore object.
 #Add-PSSnapin Interop.AZROLESLib -ErrorAction SilentlyContinue
 $AzStore = new-object -com AzRoles.AzAuthorizationStore
 # Initialize the authorization store.
 # Refer to https://msdn.microsoft.com/en-us/library/windows/desktop/aa376359(v=vs.85).aspx for initialize parameters
 $AzStore.Initialize(0,"mssql://Driver={SQL Server};Server=MIM;/AzManStore/O365.Licensing")
 $AzStore.UpdateCache($null)
 # Create an application object in the store.
 $qbeApp = $AzStore.OpenApplication("O365")

 # Create HashTable of all group/assignedLicenses associations
 $licenseAssociations = @{}
 $licenseAssociations.Add("Groups",@{})

 # The following is to demonstrate what the PowerShell connector would look like which acts as a lookup-table to join on each users "memberOf" property - thereby
 # allowing for multiple licenses

 # Loop through all role assignments to return the role for each member MemberNames
 foreach($assignment in $qbeApp.RoleAssignments) {
 #$assignment
 foreach($member in $assignment.MembersName) {
 #$member # AD Domain\Group
 $groupDNAD = (Get-ADGroup -Identity $($member.Split('\')[1])).DistinguishedName
 $groupDN = "CN=$((Get-ADGroup -Identity $($member.Split('\')[1])).name),OU=LicensedUsers,DC=IdentityBroker"
 #$assignment.Name # EMS role
 $role = $qbeApp.OpenRole($assignment.Name)
 foreach($def in $role.RoleDefinitions) { # disabled plans
 #$def.Description # SKU
 #"$($def.Description):$tasks" # assignedLicenses
 $tasksAsString=""
 $tasks = @{}
 foreach($task in $def.Tasks) {
 $obj = [PSCustomObject]@{
 Name = $task
 Seq = [int]($qbeApp.Tasks | Where-Object {$_.IsRoleDefinition -ne 1 -and $_.Name -eq $task}).Description
 }
 $tasks.Add($task,$obj)
 }
 foreach($task in $tasks.Values | Sort-Object Seq) {
 if($tasksAsString.Length -gt 0) {
 $tasksAsString+=";"
 }
 $tasksAsString+="$($task.Name)"
 }
 }
 $assignedLicense = $def.Description
 if ($tasksAsString.Length -gt 0) {
 $assignedLicense += ":$tasksAsString"
 }
 $licenseAssociations.Groups.Add($groupDN,@($groupDNAD,$assignedLicense))
 }
 }

 #Repeat/loop through each item in a target system
 foreach($group in $licenseAssociations.Groups.Keys) {
 $group
 $licenseAssociations.Groups.$group[0]
 $licenseAssociations.Groups.$group[1]
 }

 $AzStore.CloseApplication($qbeApp.Name,0)
# -- END Connector Script

 

Note that the script above outputs the groupDN and assignedLicenses  properties to the console – for your own MIM connector implementation you will need to take this to the next steps yourself, i.e. essentially merging the group-keyed data with user-keyed data, joining on user.memberOf, and present a consolidated data set to MIM in the form of a User License Entitlements MA.

Important Important: The script now takes care to order tasks as “disabled plans” according to the (integer) index (stored in the task description).  This ensures that the assignedLicenses are reflected back in the order that they were sent (vital for a sync configuration with MIM).

Conclusion

While I won’t go into the specifics of the MIM side of the implementation – mainly because the preferences for this will vary from place to place – I trust that I have presented a repeatable approach that can get us away from the ongoing pitfalls of either a scripted approach, or any other sync approach which does not provide the same levels of extensibility and manageability.

In my case user volume levels meant that a MIM PowerShell MA was not going to suffice, and I needed to use UNIFY Identity Broker to provide the scalability and throughput to meet target SLAs, others may find that a PowerShell MA approach is adequate – at least for now.  If anyone is interested in exactly how I took this idea to the “next level” in this way, I would be more than happy to elaborate – but for now I felt that it was important to share the above approach as a superior way forward to Automatically Assign Licenses to Your Office 365 Users.

Footnote

Some of you will be aware that AzMan has been marked as deprecated as of Server 2012 R2, which means that this will be the last version of the OS which will incorporate this feature.  In case you’re wanting more info on this, read this MS blog post.

However, rest assured I took this into account when investing energy into the above solution – noting that it will be “… well into 2023 before we see the last of AzMan” and by then I am expecting there to be an even better way of providing role/rule-based license allocation for Office 365.  Regardless, I needed something which:

  • Supported the O365 licensing data structure I was modelling;
  • Had a “free” UI which allowed me to link to AD groups; and
  • Had an API which I could use to firstly read the data the way I needed to, as well as load the data from a master source.

… and this definitely ticked all the boxes for me – noting that I wasn’t actually using the main feature AzMan was designed for, namely its access checking API for buttons/panels on forms.  If I can get 6 years of use out of this between now and 2023 then great :).

Posted in FIM (ForeFront Identity Manager) 2010, MIM (Microsoft Identity Manager) 2016, Windows AzMan | Tagged , , | 9 Comments