Microsoft Forefront Identity Manager (FIM) is the successor to Microsoft Identity Lifecycle Manager (ILM). The core focus areas of FIM are managing policy, managing credentials, managing and provisioning users and groups, access control, and compliance. The product includes a Credential Management (CM) feature for use in environments that have a Public Key Infrastructure (PKI) and need to provide self-service and policy-based certificate management. While FIM is typically thought of as a solution for smart-card enrollment and life-cycle management, it excels at providing policy management for any certificate type. In light of the new product name, the community has struggled to differentiate between what was the synchronization engine and the product itself, not wishing to drag CM into what has typically been an MIIS/ILM/FIM conversation. In cases where differentiation is important, the two server products are usually referred to as the “sync engine” and Certificate Lifecycle Manager (CLM); however, for the purposes of simplification in this chapter, we will use the term ILM to refer to the sync engine.
FIM is a robust .NET application platform built on Microsoft’s highly successful database platform—SQL Server. FIM provides services for the synchronization and reconciliation of identity data, and in some cases passwords, between multiple disparate repositories, including (but not limited to):
Enterprise directories
Active Directory/Active Directory Application Mode
Novell eDirectory
Sun Directory Server
IBM Tivoli Directory Server
Databases
Microsoft SQL
Oracle
IBM DB2
Microsoft Exchange Server
Lotus Notes
Flat text files
DSML
LDIF
Attribute Value Pair
CSV
Delimited
Fixed width
FIM is considered to be in a class of products known as metadirectory synchronization tools. This is in contrast to other products like virtual directories that have no central reconciliation or synchronization mechanism.
For an up-to-date list of supported FIM management agents, visit TechNet.
While the depth of connector coverage for identity management products is often a popular topic, it is typically irrelevant for two reasons:
FIM is a SQL Server application, and with SQL Server comes connectivity via ODBC, Linked Servers, and Integration Services, all of which provide access to databases and systems that do not have native management agent support.
FIM has what is known as the Extensible MA for Connectivity (XMA or ECMA), which is a framework for writing your own MA to proprietary applications and platforms; the XMA allows you to write the connectivity components and hand them back to FIM using its standard interface.
Given the options for aggregating data sources through SQL Server or creating an XMA to consume a custom interface or web service, FIM provides an extremely flexible platform on top of which to develop an identity management solution.
While the term MA is fairly common in the Microsoft community, the generic term connector is also commonly used across multiple identity management products.
Each FIM component has a specific set of prerequisite software, with the high-level pieces listed here:
All of the FIM components rely on Windows Server 2008 at a minimum.
Either version or edition is sufficient; however, x64 editions are supported only if the SQL server and the FIM server are loaded onto separate servers.
SharePoint is used for the FIM Portal, FIM Password Registration portal, and FIM Password Reset portal.
While not strictly required, most deployments make use of Visual Studio 2008 or later to build and compile rules extensions.
In previous versions of FIM (e.g., ILM/MIIS), there was sometimes a performance benefit when collocating with SQL. However, with FIM 2010 R2, it is recommended that you separate SQL onto a dedicated server (or cluster) and avoid collocating FIM components with SQL.
While FIM itself does not officially support failover clustering of the application, some users have noted that it works using a Cluster Generic Script resource. For most deployments, deploying a supported topology is the best course of action. FIM does support Network Load Balancing (NLB), which can distribute the processing load of the FIM Service.
The really attractive thing about FIM is that it is a streamlined .NET engine for synchronizing and reconciling identity information. That, in effect, is all it does, and it does it really well. What makes the product so versatile is that at pretty much any point in a data flow you can “go to code” via an extension, resolve the issue in your preferred .NET language, and return the manipulated data back to your data flow. All the product does is take information from one source, and transform it or flow it to another source. We’re hoping the power of the tool will begin to make itself more apparent as you read on.
The synchronization engine is an application that relies completely on SQL Server, and all data, code, rule sets, attribute flows, and consolidated data sets are stored within SQL tables (see Figure 21-1).
Since FIM is a complex application and not something most AD administrators have experience with, we are going to discuss the basic features and terminology in more depth.
There are several terms that you will hear attributed to a data source within FIM: data source, directory, and connected directory (CD). “CD” can refer to a database, a flat file, or a full-fledged directory such as Active Directory.
There are two ways we can get data into the product for processing: full imports and delta imports. Since AD exposes delta changes natively via DirSync, you are spoiled into thinking you can do delta imports with any CD, but that is not the case. When data is brought in for processing, it’s stored in a special location called the Connector Space (CS).
Also called “staging,” full imports read the entire CD every time. Full imports can be scoped or limited to specific containers or organizational units, and the entire MA can be scoped to process only specific object types.
If the CD is capable of differentiating changes like AD is, you can ask the CD for objects that have changed since your last full import. The caveat here is that you always have to start with at least one error-free full import in order to get a delta import.
You get data into FIM by “staging” the data into a special area called the Connector Space (CS) through a full import. Subsequent imports may be able to utilize delta imports if the CD supports it.
In Figure 21-2, the (A) actions depict the import process from CD to CS. While this could be a full or a delta import, the very first import should always be a full import.
Technically speaking, the connector space is just a table in SQL, but the important concepts to understand here are that the CS is where objects go once they’ve been staged (through either a full or delta import) and that the CS effectively becomes a localized copy of the CD you’re connecting to. From that point on, all of the processing happens against the objects in the CS—not directly against the CD; this is an important distinction between a metadirectory product, like FIM, and a Virtual Directory. This is a good thing because you can grab a copy of the data and then build and validate your rules against it without risking data corruption, access rights, or network traffic. Getting objects staged into the CS takes minutes to set up and is limited only by your rights to read the directory and the time it takes to iterate through the directory and create the entries in SQL.
Now, this is very important: before you can read from an Active Directory connected directory, the account you will use to connect must have at least the Replicating Directory Changes right. For information on how to set that up, refer to the KB article.
Beyond this detail, any authenticated user can read public attributes; however, sooner or later you may run into areas of the directory that require greater access rights.
Once objects have been staged into the connector space, they can synchronize with another section of the engine called the metaverse.
The metaverse (MV) holds the consolidated representation of identities from each connector space. For instance, if you have an account in AD LDS and an account in an AD domain, and both have been staged into their respective connector spaces, you can choose to represent those objects either independently through a process called projection, or as a single object through a process called a join. As a general practice, the MV holds a single object representing the consolidated identity information mined from objects in the individual data sources; think of it as a many (CS) to one (MV) relationship. Most importantly, the way data is synchronized from one CS to another CS is through the MV. Without an MV object, you cannot flow information between one CS and another. So what’s this we were saying about projection and joins?
One of the immutable laws of FIM is that every MV object has to start out its life cycle as a projection from one CS object. Incidentally, the converse is also true: once all of your CS objects are disconnected from an MV object, that MV object will cease to exist. A projection rule simply states, “Create an MV object of a specific type for this specific CS object.”
Once you’ve projected a set of CS objects into the MV, you can set up some rules for objects in another CS to join the MV object. There are tons of ways you can specify this, but once you have two CS joined via a common MV object, you can then synchronize data between the respective CS and MV objects, creating a “bridge” of sorts.
After using a full or delta import to stage data into the CS, we can then project those objects into the MV using a projection rule. Objects in a separate CS can be connected through an MV object through the join process, which allows for the synchronization of data between connected objects.
Now, projecting an object into the MV doesn’t mean that any of its data goes with it. On the contrary, we have to create attribute flow rules to tell the engine exactly which CS attribute goes to which MV attribute. Before we can discuss how synchronization works, we need to talk briefly about connectors, what states they can be in, and how we can filter them.
In Figure 21-3, action (1) depicts the projection of a CS object into the metaverse, which results in the creation of the MV object, while action (2) depicts inbound attribute flow.
In Figure 21-4, actions (3) and (5) depict joins occurring between CS objects in the file and AD, respectively, while actions (4) and (6) depict inbound and outbound attribute flow.
Whenever you project a CS object into the MV, a connector is created. Of particular importance is the type of that connector—in this case it is considered a normal connector. You can also create connectors of type explicit, and you can remove a connector by disconnecting it. When an object is first staged into the CS, it is a normal disconnector. If that object is joined or projected, it becomes a normal connector. Suffice it to say that normal disconnectors can become connectors again, whereby if it is explicit then it must be manually made a connector or disconnector.
If you disconnect an existing connector, you can place that disconnector as one of two types: a normal disconnector or an explicit disconnector. A connector is really just a special relationship between CS and MV objects that absolves the need to reevaluate the relationship every time a sync is run, which makes the connector a static entity within the engine. This is an important concept to understand, as join rules for a particular CS object are evaluated only under two conditions: the CS object is not currently connected, and the CS object is not assigned as an explicit disconnector. Once a join is made the rule is never executed again for that CS object.
The bottom line here is never to create anything that is explicit, and your life will be much easier—explicit disconnectors are designed to provide a temporary state until information can be “breadcrumbed” back into the originating system, and are not intended to be a permanent solution (although for many people, they are nonetheless a permanent problem).
There are two basic types of Identity Management (IdM) products on the market today: state-based and event-based. FIM is a state-based product, which simply means that things happen when an object or attribute changes state. Where event-based systems are concerned, an event is generated based upon some predefined threshold or application trigger that tells the IdM system to do something. Without devolving into a religious discussion regarding which is better, the first truth you need to understand is that all systems on the market today have aspects of both systems. While one system may claim to be one or the other, all products include both state- and event-based aspects. The important thing to note is how you approach a problem with one system versus another. The only thing you need to understand is that as a synchronization engine, the product will process each object in turn (serially) and resolve the state of that object (and all of its attributes) completely each and every time that object is touched. This is probably the most difficult concept to understand with the product, and it generally confounds people trying to understand why full or delta synchronizations cause extensions in other management agents to fire. (Don’t worry, we’re not there yet.)
The problem facing any IdM product vendor is that if you change the set of rules for synchronization of data, then how do you reapply those new rules to objects that have not been triggered by an event or state change? We’ll come back to this, but suffice it to say that this product enforces the current set of rules against all objects when a full synchronization is run; so full synchronization reconciles every connector. Running a delta synchronization applies the current rule set to objects that have changed, or are currently disconnected, since the last full or delta import (i.e., the state changed).
Forces all rules and attribute flows to process every object in the CS. This ultimately will flow data from the CS to the MV and out to any other CS that is joined to the MV object in question.
Forces all rules and attribute flows to process only the objects in the CS that have changed since the last synchronization. This will flow data from the CS to the MV only for changed objects.
It is important to recognize that the process of reconciliation is critical for issues of compliance. Products that do not ensure full reconciliation for all objects are not telling you the whole story.
We use full or delta imports to stage data into the CS, but we also do full or delta syncs to copy data between the CS and the MV. The important thing to note is that while imports are always one-way (import, not export), synchronizations are always two-way (import and export). There is simply no way around this—if you have export attribute flow rules set up, they must be processed to complete the state evaluation of every object, even if you only intend for this to happen in one place. If that CS object is tied to a CS object through an MV object (through a join), then a sync run on one CS will process changes all the way to the other CS object.
Figure 21-5 depicts normal synchronization convergence. Running a full or delta sync will cause synchronization to occur across all three connectors; however, inbound attribute flow only occurs on the management agent that the synchronization was triggered from (depicted as the DB-connected directory).
Now that we’ve talked about how to get data into the CS and sync it with an MV object, we need to talk more about management agents. We will touch on attribute flow in a moment.
The management agent (MA) is a set of processes comprising the native APIs of the product we are connecting to combined with a nice little GUI to configure it. All the stuff we talked about—imports and syncs, joins and projections, and connector filters—is part of the management agent itself. In fact, it is not an agent at all—at least not in the sense that you have to install anything on the CD. This is a fundamental difference between state-based and event-based products: event-based systems require some sort of agent or driver that must reside on the system or application in question, whereas state-based systems require nothing but a local instance of the APIs in question.
To get the APIs needed for connectivity to Lotus Notes, the Lotus Notes client needs to be installed on the FIM server. The same can be said for Oracle connectivity requiring the Oracle client, SQL connectivity requiring the SQL client, and so on.
The MA is responsible for determining how you connect to the CD, which object types you want to see (e.g., user, group, or computer), and which attributes you care to have copied to the CS. Only selected attributes can flow into the MV through attribute flow.
Sometimes the terms MA and CS are used interchangeably, but while they represent the entirety of the CS relative to the CD, they are much more. The MA is where you store the credentials for connecting to the CD, as well as all of the connectivity, scopes, filters, join and projection rules, attribute flows, deprovision rules, extension configuration, and password sync setup. Suffice it to say that you will have one MA for every CD you want to talk to, which will be represented by its own CS.
MAs also provide a way to store and represent sets of potentially schedulable operation profiles, called run profiles.
You tell FIM that you want to perform a full import or a delta sync by creating a series of run profiles that contain at least one of the following prebuilt operations:
Full import (stage only)
Delta import (stage only)
Full synchronization
Delta synchronization
Full import and delta synchronization
Delta import and delta synchronization
Export
The export operation is solely for exporting pending changes in the CS out to the CD. This is critical for actually sending the changes back to the directory. You should feel reassured to know that the product cannot automatically affect the CD simply by manipulating objects in the MV or the CS. You must do an export to send changes out. Consequently, if the credentials you supplied to the MA do not have rights to modify the requested attributes or create a newly provisioned user, for example, the exports will fail. The credentials in the MA must have all of the appropriate rights to affect the pending changes.
You can also string combinations of operations together in one profile. For instance, you might want to start with a delta import and delta synchronization and follow that immediately with an export, followed by a delta import. That would get data in, process it, and send it back out with the changes, all in one run.
At this point, don’t worry too much about the “special” run profiles; you’ll touch on them more if you begin working with the full product. But suffice it to say that they pretty much do what you’d think, with one exception. The “delta import delta synchronization” profile will only synchronize changes that were imported as part of the current delta import. This is not the same as performing the same two operations in separate steps.
Now, before we talk about attribute flow we need to talk briefly about the Metaverse Designer.
Suppose you have an attribute in your AD called extensionAttribute3
, but it really
represents your cost center. What you’d really like to do is just call
it “Cost Center” in the MV so that it actually makes sense when you
decide to flow this to some other CS. With the Metaverse Designer you
can create custom object types and attributes as needed and you don’t
have to have OID numbers like you do in AD. You can create a costCenter
of type String (indexable)
, make it multivalue or
not, index it if you want to, and assign it to the person
object class. You can then flow data
into that from any CS as long as it is of type String
.
The Metaverse Designer is what you use when you want to add custom attributes to objects in the metaverse.
Simply stated, an attribute flow rule is a
mapping between a CS attribute (such as extensionAttribute3
) and an MV attribute
(such as costCenter
). An attribute
flow can be either import or export, and either direction can be one
of the following mapping types:
Flowing data from a CS attribute to an MV attribute of the
same type (e.g., String/String
). The attribute names
can be completely different, but you just want to flow the data
over unaltered—for example, flow EIN
into employeeID
.
There are three types of advanced flows:
Flows data from one or more CS attributes to a single MV attribute, whereby the data needs to be transformed or concatenated in some way. The attributes can even be of different types, as long as you perform the type conversion within the code. The term extension implies that we have to write code to accomplish this mapping. For example, take a user’s last name and add the first character of the first name to form the logon ID.
Flows a constant or arbitrary String
to a single MV object of
type string
. Since it’s
a constant, the data is not originating from any CS
attribute. No code is required; however, if you want to
“blank” out an attribute (flow a null), you have to do
this with an extension—as of SP1,
this was not an option available in the GUI. For example,
everyone’s company attribute is “My Company.”
Flows a component of a DN into an MV object of type
string
. You can pick
apart a large DN by choosing which section of the string
to flow across. No code is required, unless you want to
transform the component itself, and then you’re back to
the extension. For example, you know that the second
component of the DN is always the department name, so flow
that information unaltered into the department
attribute.
This is available only for importing attribute flows into the metaverse; it cannot be used to export components of a DN to another CS. To do that, you need to flow the component into an MV attribute and then set up a direct export attribute flow to the CS.
With any rules extension, you have the opportunity to resolve the situation in any .NET language. The good news is that if you are a VB.NET or C# programmer, FIM will create the entire project template for you. You will find the greatest number of examples online in VB.NET, and that is the language we will use in this chapter.
MAs are used to connect natively to a CD; they define the objects in which you are interested, whether those objects should be filtered, how they are joined or projected, and what attribute flow rules exist between the CS and MV. You can create custom attributes to flow information into the MV through the Metaverse Designer, and run profiles are used to bundle together various methods to pull data into the CS and synchronize it with the MV.
FIM also supports password management via a web-based application and password synchronization from AD to other systems. Many additional scenarios are covered in the Microsoft Identity and Access Management Series (refer to See Also).
Figure 21-6 outlines the example scenario of synchronizing AD from an HR database, which is used throughout this chapter. The numbered points will be referenced in later recipes.
We’ll start with an employee database that runs on SQL Server, referred to from now on as the HR Database.
Let’s walk through how FIM will synchronize the HR Database with Active Directory and define some of the specialized terms Microsoft uses to describe the process. The numbers in parentheses refer to the numbered points in the diagram.
First, we will import or stage (1) records from the HR Database into the HR Database MA connector space. The import process creates connector space objects (2).
Next, we will synchronize the data in the HR Database MA connector space. The first time we do this, and any time FIM discovers a new user record in the MA connector space, FIM will project (3) a new object (4) into the metaverse, and join, or link, the HR Database MA object to the metaverse object. FIM will then flow attribute data from the HR Database MA connector space object to the joined metaverse object through the MA’s rules (5).
Synchronizing the HR Database MA will also provision (6) a new connector space object (7) in the Active Directory MA’s connector space and join the new Active Directory connector space object to the metaverse object (4). FIM will then flow the appropriate attribute information from the metaverse object (4) into the AD connector space object (7) through the Active Directory MA’s rules (8).
We will export (9) objects (7) from the AD connector space into Active Directory itself to create Active Directory user objects (10).
We will also import (11) the telephoneNumber
attribute from AD user
objects (10) into the related AD connector space objects (7) and
synchronize the AD management agent. This will flow attribute data
through the ADMA rules (8) and into the joined metaverse object (4);
from there, attribute data will flow through the HR Database MA’s
rules (5) to the joined HR Database MA connector space object (2). At
this stage, the updated HR Database MA connector space object (2) will
be exported (12) to the HR Database, resulting in the [telephoneNumber]
column being
updated.
We also will test deprovisioning by deleting a row in the HR Database and then importing (1) objects from the HR Database into the HR Database connector space. This will result in the related connector space object (2) being marked as deleted. Synchronizing the HR Database MA will cause the joined metaverse object (4) to be deleted. This will, in turn, cause the joined AD connector space object (7) to be deleted. Finally, the delete operation is exported to Active Directory, resulting in the deletion of an Active Directory user object (10).
Microsoft provides a great deal of useful documentation for MIIS on its website. This section lists some of the most useful documents:
FIM comes with a very useful and complete help file. You can find it in the FIM Synchronization Service installation folder, typically at C:Program FilesMicrosoft Forefront Identity Manager2010Synchronization ServiceUIShellHelpfiles. The file is named mms.chm, and it contains general help for configuring and running FIM.
The FIM home page is the starting point for all the current information about FIM, including recent releases and other news.
The first stop for technical and training information for FIM can be found at the product page.
Here you can find the link to the FIM forum, which is frequented by the product team as well as many of the FIM MVPs.
This document provides an overview of FIM and describes core scenarios of the product features. Visit the FIM 2010 Technical Overview.
The guide contains a series of articles covering the requirements and installation of FIM.
The Documentation Roadmap contains a series of links that include an overview of the newest features and a complete series of links walking through the various features and functions.
There are several virtual labs for FIM that are available as free downloads. Each download includes FIM and a manual, along with a 90-minute block of lab time.
You want to get employee records from a SQL Server database to FIM so that they can be used as the source for new accounts in AD.
You need to start by creating a management agent (MA) for the SQL Server database:
Click the Management Agents button on the toolbar.
In the Actions pane on the right, click Create.
In the Create Management Agent Wizard, select SQL Server from the “Management Agent for” drop-down list.
Type HR Database
into the
Name text box.
Type a description in the Description field—this is where you can be creative.
Click Next.
In the Connect to Database pane on the right side:
Type the SQL server name into the Server Name text box.
Type the name of the database in the Database text box.
Type the name of the table or view that contains the employee records in the Table/View text box.
Leave the Delta View and Multivalue Table text boxes blank.
Select the radio button for the type of authentication the SQL server is set up to use.
Fill in the User Name, Password, and Domain text boxes with the credentials of a user who has permissions to read and update the table we will create.
Click Next.
On the Configure Columns page:
Click the Set Anchor button. This will display the Set Anchor dialog box.
In the Set Anchor dialog box, select Badge Number and click the Add button.
Click OK to save the anchor attribute definition and then click Next.
On the Configure Connector Filter page, click Next.
On the Configure Join and Projection Rules page, click Next.
On the Configure Attribute Flow page, click Next.
On the Configure Deprovisioning page, click the “Make them disconnectors” radio button.
Click Next.
On the Configure Extensions page, click Finish.
Following these steps will create a SQL Server management agent. Associated with the MA is a namespace known as the connector space. FIM will store the data from the relevant columns of the database here and use them to provision, synchronize, and deprovision user accounts in Active Directory. Creating the SQL Server management agent is the first of several steps to get the data into FIM. You should now see a management agent in the Management Agents pane of the Synchronization Service Manager with the name and comments displayed.
Creating an Active Directory Management Agent for more on creating a SQL Server MA
The first step to accomplish this is to create an Active Directory management agent (in Creating a SQL Server Management Agent, see (13) of Figure 21-6):
Click the Management Agents button on the toolbar.
In the Actions pane on the right side, click Create.
In the Create Management Agent Wizard, select Active Directory Domain Services from the “Management Agent for” drop-down list.
In the Name box, type a name. The forest name is usually a good choice.
If you feel creative, type a meaningful description into the Description text box.
Click Next.
In the Connect to Active Directory Forest pane on the right side:
Type the fully qualified DNS name of the forest into the Forest Name text box.
Fill in the username, password, and domain name of an appropriate user account. The account must have sufficient access permissions. See this recipe’s Discussion for more details.
Click Next.
In the Configure Directory Partitions pane on the right side:
Select the domain(s) you wish to manage in the Select Directory Partitions field.
Click the Containers button in the lower-right portion of the dialog box.
In the Select Container dialog, select the containers you wish to manage.
Click OK.
Click Next.
On the Configure Provisioning Hierarchy screen, click Next.
On the Select Object Types screen, select the user object type and then click Next.
FIM requires that the organizationUnit
, domainDNS
, and container
object types always be
selected. FIM uses these objects to maintain the hierarchical
structure of Active Directory in the MA’s connector space.
In the Select Attributes pane on the right side, select the
attributes you wish to manage from the Attributes field. You can
check the Show All checkbox to display a full list of all attributes
in the AD. Some AD attributes are mandatory; a typical minimal list
would be cn
, displayName
, employeeID
, givenName
, sAMAccountName
, sn
, userAccountControl
, userPrincipalName
, and unicodePwd
. (You need to select the Show
All checkbox to see the unicodePwd
attribute.) Click Next to save
the selected attributes.
On the Configure Connector Filter page, click Next.
On the Configure Join and Projection Rules page, click Next.
On the Configure Attribute Flow page, click Next.
On the Configure Deprovisioning page, click “Stage a delete on the object for the next export run” and then click Next.
On the Configure Extensions page, click Finish.
The account used to connect to AD must have the following rights to the containers that you intend to write to:
Standard
Read
Write
Advanced
Delete
Replicate directory changes
Create all child objects
Delete all child objects
List contents
Read all properties
Write all properties
Delete subtree
Read permissions
All validated writes
A popular question that surfaces in the discussion boards has to do with why FIM doesn’t support the use of anonymous binds to LDAP directories. While there is quite a bit of development involved in connecting to a given directory’s change log for the purposes of being able to process deltas, there was obviously a hard choice made during the original product planning to avoid direct support for binding anonymously. Most of the use cases involving FIM have to do with ongoing delta processing, so supporting an anonymous bind provides little or no value except for the small percentage of cases where a quick solution precipitates the need for an anonymous bind. If you find yourself in the latter situation, consider using ldifde or another tool to extract the directory to an LDIF file for processing or build an extensible MA (XMA).
You have decided on a single authoritative source for new employees: a SQL Server database. When a user record is deleted from it, you want FIM 2010 R2 to delete the corresponding Active Directory account.
One of the configuration options required to have deletions propagated from a SQL Server database to Active Directory is the metaverse object deletion rule:
Click the Metaverse Designer button on the toolbar.
In the Actions pane on the far-right side, click Configure Object Deletion Rule.
Select the “Delete metaverse object when connector from this management agent is disconnected” radio button and ensure that the SQL Server database MA has a checkmark in the box next to the name.
Click OK.
The object deletion rule informs FIM of when to delete metaverse objects. Deleting a metaverse object does not necessarily cause anything to happen in the connected data source, but it does disconnect any connected objects in all of the connector spaces. This will cause the deprovisioning rule to fire for each disconnected object. The deprovisioning rule is configured for each management agent in the Configure Deprovisioning page for the management agent.
It is critical to plan accordingly for the life cycle of every object. In many cases, deleting the MV object is not desirable if not all of the connectors are to be deleted. If you find yourself needing to maintain objects in other connected directories even after an authoritative source object has changed to an inactive status or been removed entirely, consider leaving the connectors in place and allowing the default metaverse object deletion rule to prevail. This is incredibly helpful if you are doing any sort of reporting based off of aggregated identity data derived from the metaverse.
Creating a SQL Server Management Agent; Deleting Data in the Connector Space and Metaverse for deleting data in the connector space and metaverse; Creating a Run Profile for Provisioning for the provisioning run profile
You have already created the MAs you need, but you want to flow the column data from a SQL Server database to attributes in Active Directory.
You need to configure the AD MA’s attribute flow rules page (in Creating a SQL Server Management Agent, refer to (5) in Figure 21-6):
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the SQL Server database MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “person” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the Data Source attribute list, select the attribute whose data you wish to flow into the metaverse. (See for some suggestions.)
In the Metaverse attribute list, select the attribute you want the data to flow into. (See for some suggestions.)
In the Mapping Type section of the dialog, select Direct.
In the Flow Direction section of the dialog, select Import.
Click New. The new attribute mapping will appear in the attribute mapping list, with an arrow indicating that it is an import attribute flow.
Click OK.
FIM has been configured to flow an attribute from the SQL Server database MA’s connector space into the metaverse. In general, we can map any attribute from the connected system to any attribute in the metaverse. However, if a Mapping Type of Direct is issued, the attributes in the MA and the metaverse must be of the same data type (e.g., string or integer). To map from one data type to another, configure the advanced attribute flow (see Defining an Advanced Import Attribute Flow).
Here are some typical simple mappings:
FirstName
→givenName
LastName
→sn
Dept
→department
StaffNumber
→employeeID
TelNo
→telephoneNumber
You need to make your own decisions about what data in the SQL
Server database maps onto what data in the metaverse attributes, but
these are usually fairly obvious. If you want to construct a name—for
example, you’d like the sAMAccountName
to be derived from the first
character of the first name prepended to the last name—you need an
advanced flow.
As a rule of thumb (and personal preference), it is generally better to do advanced flows to assemble data on the inbound flow so that the correct information is contributed to the metaverse. This approach scales better since syncs process only the inbound attribute flow for the MA that the run profile was executed from, and having direct flows on all outbound attribute rules translates to less overhead for converging a single identity. So consider moving as many of your advanced rules to import flows as possible, and use advanced rules only when necessary for export flows.
Creating a SQL Server Management Agent; Setting Up a Simple Export Attribute Flow to Active Directory for setting up a simple export attribute flow to AD; Defining an Advanced Import Attribute Flow for defining a more advanced attribute flow; Implementing an Advanced Attribute Flow Rules Extension for writing a rules extension to take the advanced flow even further (all these flows are eventually exported to AD)
You want to flow attributes in the metaverse to attributes in AD.
For example, the givenName
field in
the metaverse needs to map to the givenName
field in AD.
You need to configure the attribute flow pages on the AD MA (in Creating a SQL Server Management Agent, refer to (8) in Figure 21-6):
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the AD MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “user” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the data source attribute list, select the connector space attribute you want to flow data into. See Discussion for some suggestions.
In the Metaverse attribute list, select the attribute you want to flow data from. See Discussion for some suggestions.
In the Mapping Type section of the dialog, select Direct.
In the Flow Direction section of the dialog, select Export.
Click New. The new attribute mapping will appear in the attribute mapping list, with an arrow indicating that it is an export attribute flow.
Click OK.
This will configure a simple export attribute flow from the metaverse to the AD MA. You need to determine what attributes in the metaverse should flow to AD attributes.
Here are some typical simple mappings:
givenName
→givenName
sn
→sn
department
→department
employeeID
→employeeID
telephoneNumber
→telephoneNumber
cn
→displayName
cn
→cn
uid
→sAMAccountName
In many FIM scenarios, data is manipulated on its way
into the metaverse, and then copied on its way out
to other connected systems. In this example, the cn
comes from the displayName
. This is because you will later
create an advanced import flow that will write the first name followed
by a space and the last name into the displayName
in the metaverse. Something
similar will be done for uid
, only
you will take the first character of the first name and append the last
name; for example, Fred Smith gets an sAMAccountName
of
FSmith.
Creating a SQL Server Management Agent; Setting Up a Simple Import Attribute Flow; Defining an Advanced Import Attribute Flow; Implementing an Advanced Attribute Flow Rules Extension (these recipes are interesting because most of the data you are exporting to AD in this recipe was first imported from them)
You want to create an Active Directory username using the first and last names from a SQL Server database. Simple attribute-to-attribute mapping is not sufficient. You need to take partial strings from different attributes and combine them to form a new name.
This will involve writing some VB or C# code for an advanced attribute flow, which is covered in Implementing an Advanced Attribute Flow Rules Extension. To start, you must define the flow rule—an entity that connects the UI elements to the coding we will do later (refer to (5) in Figure 21-6):
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the HR Database MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “person” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the Mapping Type section of the dialog, select Advanced.
In the Flow Direction section of the dialog, select Import.
Select FirstName
and
LastName
from the data source
attributes text box. (To select multiple entries, hold down the Ctrl
key.)
FirstName
and LastName
in this example are the names
of fields in the SQL Server database. Your available field options
will depend on the database used.
Select cn
from the
Metaverse attribute list.
Click New.
In the Advanced Import Attribute Flow Options dialog, delete
the default name, type cn
, and
then click OK. The flow rule name you defined here will appear in
the VB or C# code you will write later. A convention among MIIS
developers is to use the name of the destination attribute (in this
case, cn
).
Notice that in the Type column in the upper pane, the newly created attribute mapping is detailed as Rules-Extension. A rules extension is a unit of managed .NET code.
Select FirstName
and
LastName
from the Data Source
attribute mapping list. (Remember to use the Ctrl key to select
multiple attributes.)
Select uid
from the
Metaverse attribute mapping list.
Click New.
In the Advanced Import Attribute Flow Options dialog, type uid into the “Flow rule name” text box and click OK.
Notice in the Type column in the upper pane the newly created attribute mapping is detailed as Rules-Extension.
Select Configure Extensions in the lefthand pane.
Type HR DatabaseExtension
into the Rules Extension Name text box.
Click OK.
In this recipe, an advanced attribute flow rule was defined. The rule extension is implemented in managed .NET code in Implementing an Advanced Attribute Flow Rules Extension.
There are two additional types of advanced attribute flow. One is where a constant is defined that will always be written to the selected attribute. The other is used if you are flowing a distinguished name (the source attribute must be defined as a Reference DN) and only wish to flow a specific component of the DN and not the entire DN itself into a string attribute in the metaverse. No rules extension code is required for either type of advanced attribute flow. However, if you need to manipulate the attributes being flowed using code, you must define an advanced attribute flow and provide a flow rule name. Even though you may not have created the DLL that will be used at this stage, you still have to put a name in the dialog to exit the MA designer.
Creating a SQL Server Management Agent; Setting Up a Simple Import Attribute Flow for setting up a simple import attribute flow; Setting Up a Simple Export Attribute Flow to Active Directory; Implementing an Advanced Attribute Flow Rules Extension for creating a rules extension to further extend advanced attribute flow; Setting Up Advanced Export Attribute Flow in Active Directory to export data to AD
You’ve already defined an advanced attribute flow rule for the MA in the Identity Manager console. You now need to write the code and produce the DLL that implements that flow rule (refer to (5) in Figure 21-6):
Click the Management Agents button on the toolbar.
Right-click the SQL Server MA in the Management Agents pane and select Create Extension Projects→Rules Extension.
Ensure that the dialog box is filled in similar to Figure 21-7. (You can specify your own name and location.)
Click OK. This will launch Visual Studio.
This recipe assumes that you have already installed Visual Studio 2008 or later on the machine running FIM. If you are doing your development on another machine, you have two choices. You can map a drive to the FIM server and modify the code through the mapped drive, or you can copy the entire project to your development machine and work on it there. In any case, you will have to be sure to copy the resultant DLL back to the server any time you make a code change.
In the Solution Explorer in the far-righthand pane in Visual Studio, double-click the HR DatabaseExtension.vb node. This file contains the source code for your rules extension.
The main code window should show the automatically generated code. (This auto-code generation is provided for VB and C#.) The first few lines of code should look like this:
Imports Microsoft.MetadirectoryServices Public Class MAExtensionObject Implements IMASynchronization
Scroll to the code section that looks like this:
Public Sub MapAttributesForImport(ByVal FlowRuleName As String, ByVal csentry As CSEntry, ByVal mventry As MVEntry) Implements IMASynchronization.MapAttributesForImport ' TODO: write your import attribute flow code Select Case FlowRuleName Case "uid" ' TODO: remove the following statement and add your scripted ' import attribute flow here Throw New EntryPointNotImplementedException() Case "cn" ' TODO: remove the following statement and add your scripted ' import attribute flow here Throw New EntryPointNotImplementedException() Case Else ' TODO: remove the following statement and add your default ' script here Throw New EntryPointNotImplementedException() End Select End Sub
Edit this section to make the code look like this (the bold sections are new code that we typed in):
Select Case FlowRuleName Case "uid"If Not csentry("Last Name").IsPresent Then Throw New
UnexpectedDataException("No Last Name!")End If
If Not csentry("First Name").IsPresent Then Throw New UnexpectedDataException("No First Name!")End If mventry("uid").Value = csentry("First Name").StringValue.Substring(0, 1) + csentry("Last Name").Value Case "cn"If Not csentry("Last Name").IsPresent Then Throw New
UnexpectedDataException("No Last Name!") End If
If Not csentry("First Name").IsPresent Then Throw New
UnexpectedDataException("No First Name!") End If
mventry("cn").Value = csentry("First Name").Value + " ";+ csentry("Last Name").Value
Case Else ' TODO: remove the following statement and add your default script here Throw New EntryPointNotImplementedException End Select
First Name
and Last Name
in this example are the names
of fields in the SQL Server database. Your available field options
will depend on the database used.
Go to the Build menu and select Build Solution. Ensure that in the output panel at the bottom of the screen you see a message that looks like this:
---------------------- Done --------------------- Build: 1 succeeded, 0 failed, 0 skipped
Close Visual Studio.
Open Windows Explorer and browse to C:Program FilesMicrosoft Forefront Identity Manager2010Synchronization ServiceExtensions (this assumes you installed FIM 2010 R2 on the C: drive in the default location; if you didn’t, substitute the relevant parts of the path), and ensure that the DLL is present. The DLL will be called <SQL Server MA>.dll.
To be absolutely sure you have the correct rules extension selected in FIM, open the Synchronization Service Manager.
Click the Management Agents button.
In the Management Agents pane, double-click the SQL Server MA.
In the lefthand pane of the Management Agent Designer, click Configure Extensions.
Click the Select button.
Select HR DatabaseExtension.dll and click OK.
Click OK to close Management Agent properties.
Close the Synchronization Service Manager.
This code does some fairly simple string manipulation. This chapter doesn’t venture into the world of advanced FIM coding, but there are many examples in the Developer Reference off the help menu in the Synchronization Service Manager.
The FIM development environment is so flexible that human-driven digital identity business processes can be encapsulated in extension rules. However, there is no workflow engine, which means you may have to call workflow processes on another engine, such as BizTalk.
Creating a SQL Server Management Agent; Setting Up Advanced Export Attribute Flow in Active Directory for setting constants on certain attributes
Simple attribute-to-attribute mapping is not flexible enough to create the attribute values you want. You want to set constant values on some attributes. In this case, there is a bit mask of great interest: the mask used to set properties for accounts, such as whether the account is disabled.
This will involve writing some VB or C# code, like the script for advanced attribute flow covered in Configuring a Run Profile to Do an Initial Load of Data from a SQL Server Management Agent, but we must set up flow rule names for the code in this section (refer to (8) in Figure 21-6):
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the AD MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “user” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the Mapping Type section of the dialog, select Advanced.
In the Flow Direction section of the dialog, select Export.
Select userAccountControl
from the Data Source attributes list.
Click New.
In the Advanced Attribute Flow Options dialog, select Constant.
Type 512
into the Value
text box and then click OK.
Notice that in the Type column in the upper pane, the newly created attribute mapping is detailed as Constant, with an arrow indicating export attribute flow.
Click OK to close the Management Agent Designer.
Active Directory requires a minimal set of attributes in order to
create normal, usable, enabled accounts. In this recipe we have set the
required attributes. We set the userAccountControl
flag to 512
(bit 9 set), which indicates that this
account is a normal account. In other cases we might use a rules
extension and set bit 1 to disable the account; for example, if there
was an employee status field in the SQL Server database that indicated
the employee was inactive.
Creating a SQL Server Management Agent; Configuring a Run Profile to Do an Initial Load of Data from a SQL Server Management Agent; Writing a Rules Extension to Provision User Objects for writing a rules extension to provision user objects to the AD MA from objects in a SQL Server MA
Before you can run a management agent, you must create a run profile for it (refer to (9) in Figure 21-6, which shows data being loaded from AD to the AD connector space):
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the SQL Server MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the Configure Run Profiles for “<MA Name>” dialog box, click New Profile.
In the Name text box, type Full
Import (Stage Only)
and then click Next.
Ensure that Full Import (Stage Only) is selected in the Type drop-down list and then click Next.
Ensure that “default” is showing in the Partition drop-down list and then click Finish.
Click OK to create the run profile.
Three steps are required to get data into the SQL Server MA connector space:
Create the MA.
Create a run profile to run the MA.
Execute the run profile. In this recipe you have created the run profile.
It is generally a good idea to give the run profiles exactly the same names as the step type they represent. You will later create scripts that call run profiles. It is possible to give a run profile a name such as “Complete Cycle” and combine many steps in the run profile. However, when calling such entities from scripts, the calling script isn’t self-documenting, in that it hides what it is doing. It is also much easier to debug scripts when you know exactly what step is being called. Hence, you have created a run profile called Full Import (Stage Only), which consists of a single step of type Full Import (Stage Only). The one exception to this general rule is discussed in Creating a Run Profile to Export Objects from the AD MA to Active Directory.
Loading Initial SQL Server Database Data into FIM 2010 R2 Using a Run Profile for more on how to use the run profile to load data; Creating a Run Profile to Export Objects from the AD MA to Active Directory
You need to execute the run profile to load the data (refer to (1) in Figure 21-6, which shows data being loaded from the SQL Server database to the SQL Server database MA connector space):
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the SQL Server MA.
In the Actions pane on the far-right side, click Run.
In the Run Management Agent dialog, select Full Import (Stage Only) and click OK.
You’ll have to be quick if there is only a small amount of data in the database. Notice the MA says “Running” in the State column of the Management Agents pane.
In the Synchronization Statistics pane in the bottom-lefthand corner, statistics showing the number of adds are displayed. If you click the hyperlink, you can navigate to the information that was loaded.
The SQL Server database you are importing from must have records in it before FIM can import any data.
When designing a large system, work with a very small, representative set of data during development (maybe 10 records). This is because you will frequently find errors in your rules and set about deleting everything in FIM, reconfiguring your rules, and starting again. It is much better to do these initial data loads with 10 or so records rather than 100,000 records, which will take a long time to load. When you are convinced your rules are good, start working with larger data sets.
Creating a SQL Server Management Agent; Configuring a Run Profile to Do an Initial Load of Data from a SQL Server Management Agent for more on how this run profile was configured
Before you can provision and synchronize data in the AD connector space, you need to build the container structure in the connector space to reflect the container structure of Active Directory.
To do this, you have to create an appropriate run profile for the AD MA and import the AD container structure into the connector space.
The fact that you have to separately import the container structure from AD into the MA’s connector space is not obvious and is frequently overlooked by even the most experienced FIM developers. If you fail to perform this step, the synchronization process will fail when it tries to provision new objects into the AD connector space.
Refer to (9) in Figure 21-6, which shows data being loaded from AD to the AD connector space:
Open the Synchronization Service Manager.
Click the Management Agents button on the toolbar
In the Management Agents pane, click the AD MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the Configure Run Profiles dialog, click New Profile.
In the Name text box, type Full Import (Stage Only) and then click Next.
Ensure that Full Import (Stage Only) is selected in the Type drop-down list and then click Next.
Ensure that the correct domain partition is showing in the Partition drop-down list and then click Finish.
Ensure that the details in the Step Details field look like Figure 21-8.
Your partition name may be different.
Click OK.
Three steps are required to get data into the AD MA connector space:
Create the MA.
Create the run profile.
Execute the run profile. In this recipe you created the run profile.
When you create an AD MA, you specify which partitions (naming contexts) you wish to synchronize. When creating a run profile, you must be careful to select the correct partition (Naming Context in AD terms, which will usually be after the domain NC) from which to load the container structure.
A common mistake among FIM novices is to get “object does not have a parent” errors when running a synchronization step. This is because the container structure for Active Directory isn’t loaded into the AD MA’s connector space.
FIM can create missing containers based on rules, but you need to configure and write those rules. That is beyond the scope of this book.
Creating a SQL Server Management Agent; Loading the Initial Active Directory Container Structure into FIM 2010 R2 Using a Run Profile for more on how to use the run profile that was configured in this recipe; the TechNet FIM 2010 R2 Forum for many discussion threads on programming techniques for the creation of missing containers (search for “OU creation” after you have joined the forum)
You now need to run the AD MA run profile to import the AD container structure (refer to (9) in Figure 21-6, which shows the data being loaded from AD into the AD connector space):
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the AD MA.
In the Actions pane on the far-right side, click Run.
In the Run Management Agent dialog, select Full Import (Stage Only) and click OK.
You’ll have to be quick if there is only a small amount of data in AD. Notice the MA briefly says “Running” in the State column of the Management Agents pane.
Notice the Synchronization Statistics pane in the bottom-lefthand corner, where statistics showing the number of adds are displayed. If you click the hyperlink, you can navigate to the information that was loaded.
The first time you load the container structure into FIM, you need to use a full import step. Once the container structure is loaded, subsequent imports can use delta import steps, which in normal daily operations will be considerably faster to execute and will consume fewer resources on the FIM server, the AD domain controller, and the network.
Creating a SQL Server Management Agent; Configuring a Run Profile to Load the Container Structure from Active Directory for more on how to configure the run profile that was used in this recipe
The objects in the SQL Server MA’s connector space now need to be projected into the metaverse. There are three steps:
Configuring the MA for projection
Creating a synchronization run profile
Executing the synchronization run profile
Refer to (3) in Figure 21-6, which shows objects being provisioned from the SQL Server MA’s connector space to the metaverse:
Open the Synchronization Service Manager.
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the SQL Server MA.
In the Management Agent Designer pane on the lefthand side, select Configure Join and Projection Rules.
Click the New Projection Rule button.
In the Projection dialog, ensure that Declared is selected and that the drop-down list shows “person”, and then click OK.
Notice in the “Join and Projection Rules for person” frame, the columns are detailed thusly:
Mapping Group: 1
Action: Project
Metaverse Object Type: person
Click OK.
The synchronization process projects (or creates) metaverse objects that are joined to objects in the SQL Server MA connector space. When projected, FIM can provision new objects to the AD MA’s connector space. Hence, in our demonstration it is projection that initiates provisioning; however, it is perfectly legal for changes in attribute states to trigger provisioning if you have written your provisioning extensions to observe such workflows. The most common example would be looking for a change in an HR employee status attribute to trigger creation of a new account in AD. While novices often use the terms project and provision interchangeably, they mean quite different things.
From the FIM perspective, provision means “to create a new CS object in a CS where there was no object previously.” From an AD administrator’s perspective, provision generally means creation of an AD account complete with all of the standard accoutrements (home directory, terminal server profile, etc.), so it is important to be clear, depending on your audience.
Table 21-1 clarifies this and
introduces some new terminology: csentry
for connector space objects and
mventry
for metaverse objects.
Creating a SQL Server Management Agent; Writing a Rules Extension to Provision User Objects for more on provisioning
This recipe specifically covers writing a rules extension to provision user objects to the AD MA from objects in the SQL Server MA. You want FIM to provision objects to the AD MA’s connector space based on objects in the SQL Server MA.
There are three steps to provisioning:
Write a rules extension.
Configure a run profile.
Execute the run profile.
In this recipe, you will write a Provisioning-Rules-Extension. FIM will help you with the initial project creation. Refer to (6) in Figure 21-6, which shows objects being provisioned from the metaverse to the AD connector space:
From the Tools menu, select Options.
In the Options dialog, place a checkmark next to “Enable metaverse rules extension”.
Click the Create Rules Extension Project button.
Ensure that the Create Extension Project dialog looks like Figure 21-9.
Click OK.
In Visual Studio, double-click MVExtension in the Solution Explorer.
The first few lines of the code pane should look like this:
Imports Microsoft.MetadirectoryServices Public Class MVExtensionObject Implements IMVSynchronization
Navigate to the section that looks like this:
Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision ' TODO: Remove this throw statement if you implement this method Throw New EntryPointNotImplementedException() End Sub
Modify it to contain the following code:
Public Sub Provision(ByVal mventry As MVEntry) Implements ↵
IMVSynchronization.Provision
Dim container As String
Dim rdn As String
Dim ADMA As ConnectedMA
Dim numConnectors As Integer
Dim myConnector As CSEntry
Dim csentry As CSEntry
Dim dn As ReferenceValue
' Ensure that the cn attribute is present.
If Not mventry("cn").IsPresent Then
Throw New UnexpectedDataException("cn attribute is not present.")
End If
' Calculate the container and RDN.↵
container = "cn=users,DC=adatum,DC=com"
rdn = "cn=" & mventry("cn").Value
ADMA = mventry.ConnectedMAs("adatum.com")
dn = ADMA.EscapeDNComponent(rdn).Concat(container)
numConnectors = ADMA.Connectors.Count
' create a new connector.
If numConnectors = 0 Then
csentry = ADMA.Connectors.StartNewConnector("user")
csentry.DN = dn
csentry("unicodePwd").Value = "Password1"
csentry.CommitNewConnector()
ElseIf numConnectors = 1 Then
' If the connector has a different DN rename it.
myConnector = ADMA.Connectors.ByIndex(0)
myConnector.DN = dn
Else
Throw New UnexpectedDataException("Error: There are" + ↵
numConnectors.ToString + " connectors")
End If
End Sub
Notice the highlighted entries "cn=users,DC=adatum,DC=com"
. You will need
to enter your own domain and container information here.
Notice the highlighted entry mventry.ConnectedMAs("adatum.com")
. You
will need to modify this to your own AD MA name.
From the File menu, select Build→Build Solution.
Open the Synchronization Service Manager.
From the menu select Tools→Options.
In the Options dialog, click Browse.
Select MVExtension.dll and click OK to close the Options dialog.
Because you can use any .NET programming language, FIM is very flexible in a multiteam environment. As with many modern systems, it is not great programming skills that help you build good rules extensions with FIM: it is experience and familiarity with the object model. It is well worth getting to know the FIM object model. Many novices spend hours or days coding a function, only to find there is already a method on the object that does the thing they have spent all their time on.
If you are working on distributing the workload for provisioning to multiple systems (e.g., each MA is assigned to a developer or team), consider adopting the MV Router model whereby each MA is compartmentalized into its own project DLL and controlled by a single “router” DLL. In this manner, you reduce the amount of testing involved whenever code for a single MA is changed, since you are not affecting code in other projects.
Creating a SQL Server Management Agent; Setting Up a Simple Import Attribute Flow for a description of how the code in this recipe is triggered; Setting Up a SQL Server Management Agent to Project Objects to the Metaverse for setting up a SQL Server MA to project objects to the metaverse (remember, in this demonstration it is projection that triggers provisioning)
You need to synchronize data using the management agent to provision new accounts in the AD connector space. Before you can run the MA, you have to create a run profile that will synchronize the MA’s connector space with the metaverse.
You now need to create a provisioning run profile for a SQL Server MA to synchronize user objects from it to the AD MA’s connector space. The run profile step is of type synchronization:
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the SQL Server MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the Configure Run Profiles dialog, click New Profile.
In the Name text box, type Full Synchronization and then click Next.
Ensure that Full Synchronization is selected in the Type drop-down list and then click Next.
Ensure that “default” is showing in the Partition drop-down list and then click Finish.
Ensure that the details in the Step Details field look like Figure 21-10.
Notice in the Management Agent run profiles list that the Full Import (Stage Only) profile you created earlier is still there.
Click OK.
There are two types of synchronization run profiles: full and delta. A full synchronization will process every object in the connector space. This is obviously necessary when it is the very first synchronization on the data. But in normal daily operations, you only want to perform delta synchronization steps because they process only objects that have changed since the last synchronization.
Full synchronization is also used when you have made a change to the management agent configuration; for example, you have added a new attribute flow. Usually you will want to run the reconfigured MA against all of the objects in the connector space. A delta synchronization would apply the rule only to objects that had changed since the last synchronization.
Setting Up a SQL Server Management Agent to Project Objects to the Metaverse for setting up a SQL Server MA to project objects to the metaverse; Writing a Rules Extension to Provision User Objects for writing a rules extension to provision user objects to the AD MA from objects in a SQL Server MA; Executing the Provisioning Rule for executing the run profile created in this recipe
You need to run the provisioning run profile. The provisioning run profile triggers projection ((3) in Figure 21-6). The arrival of new objects in the metaverse ((4) in Figure 21-6) in turn triggers provisioning ((6) in Figure 21-6) and creates new objects ((7) in Figure 21-6) in the AD connector space. Follow these steps:
Open the Identity Manager.
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the HR Database MA.
In the Actions pane on the far-right side, click Run.
In the Run Management Agent dialog, select Full Synchronization and click OK.
Notice that the MA says “Running” in the State column of the Management Agents pane and then says “Idle.”
Notice that in the Synchronization Statistics pane in the bottom-lefthand corner, statistics showing the number of projections and provisioned entries are displayed. If you click one of the hyperlinks, you can navigate to the information that was projected and provisioned.
Inbound attribute flow is processed only on the MA that the run profile is executed against. That includes joins and projections, and since we have to have an MV object from which to provision, we will need to run a synchronization run profile against the HR MA in order to trigger provisioning to create the objects in the AD MA. If you were to run a synchronization run profile against the AD MA at this stage, nothing would be provisioned.
Setting Up a SQL Server Management Agent to Project Objects to the Metaverse for setting up the HR Database MA to project objects to the metaverse; Writing a Rules Extension to Provision User Objects for writing a rules extension to provision user objects to the AD MA from objects in the HR Database MA; Creating a Run Profile for Provisioning for creating the run profile that was executed in this recipe
There are two steps to get the data from an MA to a connected system: creating an export run profile and executing the profile. This is the first step (the second step is in Exporting Objects to Active Directory Using an Export Run Profile):
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the AD MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the “Configure Run Profiles for” pane, click New Profile.
In the Name text box, type Export
and then click Next.
Ensure that Export is selected in the Type drop-down list and then click Next.
Ensure that the correct domain partition is showing in the Partition drop-down list and then click Finish.
Click New Step.
In the Configure Step dialog, ensure that Delta Import (Stage Only) is selected in the Type drop-down list and then click Next.
Ensure that the correct domain is selected in the Partition drop-down list and then click Finish.
Ensure that the details in the Step Details field look like Figure 21-11.
Your partition name may be different.
Click OK.
We mentioned earlier that it is a good idea to name the run
profiles you create exactly the same as the run profile steps; that is,
a run profile of type Full Import (Stage Only) is named Full Import
(Stage Only). The one exception to this general rule applies to export
run profiles. When an export is completed, the only way the MA can truly
know the data was successfully written to the target data store is to
reimport the changes and compare them to what it believes was written
out. This is known as a confirming import. In AD,
for example, if we programmatically create a user account without a
password, AD will automatically disable the user account by setting a
flag in the userAccountControl
attribute. For FIM to maintain knowledge of this state, the confirming
import brings this knowledge back into FIM. Therefore, exports need to
include a confirming import stage. If the system we are exporting to
supports some form of change logging (as AD does through USNs), then the
type of confirming import can be a delta import (stage only). If the
system doesn’t expose any form of change logging (e.g., Novell
eDirectory), a full import (stage only) step will be
necessary.
FIM’s sync engine performs delta imports using the Active Directory DirSync control. You need to assign the “Replicate Directory Changes” right to the user associated with the AD MA for delta imports to work (see MS KB 303972 for instructions).
Exporting Objects to Active Directory Using an Export Run Profile for more on how to use this run profile to export objects to AD; MS KB 303972 (How to Grant the “Replicating Directory Changes” Permission for the Microsoft Metadirectory Services AD MA Service Account)
The second step is executing the export run profile to get the data into AD (the first step is in Creating a Run Profile to Export Objects from the AD MA to Active Directory). Refer to (9) in Figure 21-6, which shows the objects being exported to AD; (10) in the same figure shows the objects created in AD. Follow these steps:
Open the Identity Manager.
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the AD MA.
In the Actions pane on the far-right side, click Run.
In the Run Management Agent dialog, select Export and click OK.
You’ll have to be quick if there is only a small amount of data in the AD MA. Notice that the MA says “Running” in the State column of the Management Agents pane.
Notice that in the Synchronization Statistics pane in the bottom-lefthand corner, statistics showing the number of adds are displayed. If you click a hyperlink, you can navigate to the information that was written to AD.
Open Active Directory Users and Computers.
Navigate to the Users container.
Ensure that the user objects have been created.
User accounts in Active Directory may be flagged as disabled even
though you think they should be active. Assuming you set the userAccountControl
attribute correctly, the
usual reason for this is that some other attribute has not been set
correctly and Active Directory has disabled the account. For example, if
you do not set a password on an account, or the password you set does
not meet the domain password requirements, Active Directory will disable
the account.
If you do not set a password on a user object using the Active Directory Users and Computers MMC snap-in, you will receive a warning. If you do it programmatically, as FIM does, the account will be disabled.
By performing all the previous recipes successfully, you have provisioned user accounts from records in the SQL Server database to AD.
Creating a SQL Server Management Agent; Creating a Run Profile to Export Objects from the AD MA to Active Directory for how to configure the run profile that was used in this recipe
It is impractical to continually use the UI every time you wish to execute a run profile. You want to automate the process by calling FIM run profiles to perform the required actions.
You need to create a run profile script:
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the SQL Server MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the Configure Run Profiles dialog, select the Export run profile.
Click the Script button.
Browse to a location to save the script files.
In the “File name” text box, type SQL
Server MA Export
.
In the “Save as type” text box, select VB Script.
Click the Save button.
Repeat steps 3–9 for the other run profiles in the SQL Server MA and the AD MA. Follow the same file-naming convention.
The scripts free you from the UI and can also form the building blocks of a FIM implementation that runs unattended. You have several options, including:
Submit the scripts to the Windows Task Scheduler Service to run on a specified daily schedule. To do this, open the Task Scheduler, double-click Add Scheduled Task, and follow the steps in the wizard.
Create a Windows service that calls the scripts according to your own criteria, perhaps by submitting them to the Task Scheduler using its APIs.
Use the SQL Server Agent process to invoke run profiles on the FIM server. This approach is especially useful if you are using a SQL Server cluster and need your profiles to follow the active node in case of a failure condition.
If you already have a script execution environment, incorporate the new scripts.
Creating a Controlling Script to create a controlling script; the MSDN walkthrough about creating a Windows Service Application; the Task Scheduler API reference
You want a self-contained script that controls an entire sequence of operations; for example, import the SQL Server database records, synchronize, and then export to AD.
Before you start this recipe, you may want to make sure you have the GroupPopulatorSync.cmd and RunMA.vbs files available. Refer to See Also for the URLs.
Open Notepad.
Type this script (or copy and paste the contents of the GroupPopulatorSync.cmd file from the MIIS Scenarios, referenced in this recipe’s See Also):
@echo off rem rem Copyright (c) Microsoft Corporation. All rights reserved. rem setlocal set zworkdir=%~dp0 pushd %zworkdir% set madata=" C:Program FilesMicrosoft Forefront Identity Manager2010↵ Synchronization ServiceMaData" rem Full Import of SQL Database Records rem ------------------------------------------- cscript runMA.vbs /m:"<SQL Server MA Name>
" /p:"Full Import (Stage Only)" if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) ↵ & (goto exit_script) rem Full Sync of SQL Database Records rem ---------------------------------------- cscript runMA.vbs /m:"<SQL Server MA Name>
" /p:"Full Sync" if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) ↵ & (goto exit_script) rem Export users in to AD rem -------------------- cscript runMA.vbs /m:"<Domain FQDN>
" /p:"Export" if {%errorlevel%} NEQ {0} (echo Error[%errorlevel%]: command file failed) ↵ & (goto exit_script) :exit_script popd endlocal
In this case, insert the SQL Server MA name and domain FQDN where appropriate. This example also shows Full Import (Stage Only), which is the name of the run profile. If you named the steps differently, replace them with the appropriate name here.
Save the file with a .cmd file extension.
Close Notepad.
Open Notepad.
Type the following script (or copy and paste the contents of the RunMA.vbs file in the FIM scenarios, referenced in the “See Also” section):
option explicit on error resume next '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 'SCRIPT: runMA.vbs 'DATE: 2003-02-05 '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= '= Copyright (C) 2003 Microsoft Corporation. All rights reserved. '= '**************************************************************************** '* Function: DisplayUsage '* '* Purpose: Displays the usage of the script and exits the script '* '**************************************************************************** Sub DisplayUsage() WScript.Echo "" WScript.Echo "Usage: runMa </m:ma-name> </p:profile-name>" WScript.Echo " [/s:mms-server-name]" WScript.Echo " [/u:user-name]" WScript.Echo " [/a:password]" WScript.Echo " [/v] Switch on Verbose mode" WScript.Echo " [/?] Show the Usage of the script" WScript.Echo "" WScript.Echo "Example 1: runMa /m:adma1 /p:fullimport" WScript.Echo "Example 2: runMa /m:adma1 /p:fullimport /u:domainuser /a:mysecret /v" WScript.Quit (-1) End Sub '**************************************************************************** ' Script Main Execution Starts Here '**************************************************************************** '--Used Variables-------------------------- dim s dim runResult dim rescode dim managementagentName dim profile dim verbosemode dim wmiLocator dim wmiService dim managementagent dim server dim username dim password '----------------------------------------- rescode = ParamExists("/?") if rescode = true then call DisplayUsage verbosemode = ParamExists("/v") managementagentName = ParamValue("/m") if managementagentName = "" then call DisplayUsage profile = ParamValue("/p") if profile = "" then call DisplayUsage if verbosemode then wscript.echo "%Info: Management Agent and Profile is ↵ <"& managementagentName &":"& profile &">" if verbosemode then wscript.Echo "%Info: Getting WMI Locator object" set wmiLocator = CreateObject("WbemScripting.SWbemLocator") if err.number <> 0 then wscript.echo "%Error: Cannot get WMI Locator object" wscript.quit(-1) end if server = ParamValue("/s") password = ParamValue("/a") username = ParamValue("/u") if server = "" then server = "." ' connect to WMI on local machine if verbosemode then wscript.Echo "%Info: Connecting to MMS WMI Service on↵ <" & server &">" if username <> "" then wscript.Echo _ "%Info: Accessing MMS WMI Service as <"& username &">" end if if username = "" then set wmiService = wmiLocator.ConnectServer _ (server, "root/MicrosoftIdentityIntegrationServer") else set wmiService = wmiLocator.ConnectServer_ (server, "root/MicrosoftIdentityIntegrationServer", username,↵ password) end if if err.number <> 0 then wscript.echo "%Error: Cannot connect to MMS WMI Service <" ↵ & err.Description & ">" wscript.quit(-1) end if if verbosemode then wscript.Echo "%Info: Getting MMS Management Agent↵ via WMI" Set managementagent = wmiService.Get( " MIIS_ManagementAgent.Name='" & _ managementagentName & "'") if err.number <> 0 then wscript.echo _ "%Error: Cannot get Management Agent with specified WMI Service <"↵ & err.Description & ">" wscript.quit(-1) end if wscript.echo "%Info: Starting Management Agent with Profile <"& ↵ managementagent.name &":"& profile &">" runResult = managementagent.Execute(profile) if err.number <> 0 then wscript.Echo "%Error: Running MA <"& err.Description & ↵ ">. Make sure the correct profile name is specified." wscript.quit(-1) end if wscript.Echo "%Info: Finish Running Management Agent" wscript.Echo "%Result: <" & CStr(runResult) & ">" wscript.quit(0) '************************************************************************** '* Function: ParamValue '* '* Purpose: Parses the command line for an argument and '* returns the value of the argument to the caller '* Argument and value must be seperated by a colon '* '* Arguments: '* [in] parametername name of the parameter '* '* Returns: '* STRING Parameter found in commandline '* "" Parameter NOT found in commandline '* '************************************************************************** Function ParamValue(ParameterName) Dim i '* Counter Dim Arguments '* Arguments from the command-line command Dim NumberofArguments '* Number of arguments from the command-line Dim ArgumentArray '* Array to store arguments from command-line Dim TemporaryString '* Utility string '* Initialize Return Value to e the Empty String ParamValue = "" '* If no ParameterName is passed into the function exit if ParameterName = "" then exit function '* Check if Parameter is in the Arguments and return the value Set Arguments = WScript.Arguments NumberofArguments = Arguments.Count - 1 For i=0 to NumberofArguments TemporaryString = Arguments(i) ArgumentArray = Split(TemporaryString,":",-1,vbTextCompare) If ArgumentArray(0) = ParameterName Then ParamValue = ArgumentArray(1) exit function End If Next end Function '*************************************************************************** '* Function: ParamExists '* '* Purpose: Parses the command line for an argument and '* returns the true if argument is present '* '* Arguments: '* [in] parametername name of the paramenter '* '* Returns: '* true Parameter found in commandline '* false Parameter NOT found in commandline '* '*************************************************************************** Function ParamExists(ParameterName) Dim i '* Counter Dim Arguments '* Arguments from the command-line command Dim NumberofArguments '* Number of arguments from the command-line Dim ArgumentArray '* Array to store arguments from command-line Dim TemporaryString '* Utility string '* Initialize Return Value to e the Empty String ParamExists = false '* If no ParameterName is passed into the function exit if ParameterName = "" then exit function '* Check if Parameter is in the Arguments and return the value Set Arguments = WScript.Arguments NumberofArguments = Arguments.Count - 1 For i=0 to NumberofArguments TemporaryString = Arguments(i) If TemporaryString = ParameterName Then ParamExists = true exit function End If Next end Function
Save the file in the same folder as the previous script we created and name it runMA.vbs.
Close Notepad.
A script to control these operations, known as a controlling script, is required. You could simply create a script that called each of your other scripts in turn, but managing large numbers of scripts as the solution gets more complex becomes a problem.
Using the RunMA.vbs script
inside a batch file to create a wrapper around your run profile
execution is a common way to control when profiles get called. In a
majority of solutions, you will find yourself needing to halt the
processing of one run profile should a preceding run profile end in an
error condition. By using this process, you ensure that any errorlevel
other than 0
is an error, and you can either choose to
halt processing altogether or branch accordingly.
FIM 2010 R2 Developer Reference; the runMA.vbs and GroupPopulatorSync.cmd script files in the Group Management folder in the ILM scenarios
You want AD to become the authoritative source for the telephoneNumber
attribute of Active Directory
users.
You need to configure both the import attribute flow from the AD MA connector space to the metaverse, as well as the export attribute flow from the metaverse to the SQL Server MA connector space (refer to (5) and (8) in Figure 21-6, which show where the rules will be configured):
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the AD MA.
In the Management Agent Designer pane on the lefthand side, highlight Select Attributes.
In the Attributes pane on the righthand side, select “telephoneNumber.”
In the Management Agent Designer pane on the lefthand side, highlight Configure Attribute Flow.
In the Mapping Type section of the dialog, select Direct.
In the Flow Direction section of the dialog, select Import.
Ensure that “user” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the data source object type attribute list, select “telephoneNumber.”
In the metaverse object type attribute list, select “telephoneNumber.”
Click New.
Notice that in the Attribute Flow pane, the arrow for this mapping indicates an import attribute flow. Click OK.
In the Management Agents pane, double-click the SQL Server MA.
In the Management Agent Designer pane on the lefthand side, highlight Configure Attribute Flow.
In the Mapping Type section of the dialog, select Direct.
In the Flow Direction section of the dialog, select Export.
Ensure that “person” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the data source object type attribute list, select “telephoneNumber.”
This assumes that the SQL Server database contains a field called “telephoneNumber.”
In the metaverse object type attribute list, select “telephoneNumber.”
Click New.
Notice that in the Attribute Flow pane, the arrow for this mapping indicates an export attribute flow. Click OK.
You configured import attribute flow (IAF) from the AD MA to the metaverse and export attribute flow (EAF) to the SQL Server MA. Notice that these flows only dealt with attribute data. The object-level operations of projection and provisioning were not required because the objects already exist.
To put the new configuration to work, you will need to configure run profiles to import, synchronize, and export the data. These steps are covered in Configuring a Run Profile to Load the telephoneNumber from Active Directory.
Configure a run profile that combines import and synchronization as demonstrated in this recipe, and then execute it (see Loading telephoneNumber Changes from AD into FIM Using a Delta Import/Delta Sync Run Profile):
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the AD MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the Configure Run Profiles for “adatum.com” (the name in quotes will reflect the name you chose when creating the AD MA), click New Profile.
In the Name text box, type Delta Import and Delta Synchronization and then click Next.
Ensure that Delta Import and Delta Synchronization is selected in the Type drop-down list and then click Next.
Ensure that the correct domain partition is showing in the Partition drop-down list and then click Finish.
Ensure that the details in the Step Details field look like Figure 21-12.
Your partition name may be different, and the assumption is that you have completed the previous recipes.
Click OK.
Because a previous import step was completed in an earlier recipe, you can use the combined Delta Import and Delta Synchronization step so that FIM imports and synchronizes changes that have occurred in AD since the last time it connected. You can use this run profile from now on since it keeps track of changes internally using the DirSync control.
The Delta Import (Stage Only) step in the AD Export run profile (the confirming import from Creating a Run Profile to Export Objects from the AD MA to Active Directory) also imports changes, which suggests you could simply configure a delta synchronization run profile to process those changes in this recipe. Such an approach will work. The decision about which approach to use will depend on the service-level agreements you make. If it is two hours since the last AD import, your service-level agreement might force you to import and synchronize the changes that have occurred over the past two hours and feed them to the SQL Server database; however, you may only need to export to AD every four hours. If you only rely on the changes detected in the confirming import step, you will only be able to update the SQL Server database with changes every four hours.
Creating a Run Profile to Export Objects from the AD MA to Active Directory; Loading telephoneNumber Changes from AD into FIM Using a Delta Import/Delta Sync Run Profile for how to use the run profile configured in this recipe
With the MA and run profile created, you can now load telephoneNumber
attribute data into FIM by
executing the run profile.
In Creating a SQL Server Management Agent, (11)
in Figure 21-6 shows the telephoneNumber
data being loaded into the AD
connector space. The synchronization process then flows the data to the
metaverse ((6) in Figure 21-6) and from there to
the AD connector space ((3) in Figure 21-6).
Navigate to a user in the container you are managing with FIM.
Double-click the user object.
Ensure that the General tab is selected and then type a telephone number into the Telephone Number text box and click OK.
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the AD MA.
In the Actions pane on the far-right side, click Run.
In the Run Management Agent dialog, select Delta Import and Delta Synchronization and click OK.
Because you have changed the rules but not yet run a full synchronization on all the existing objects, a Run Step Warning dialog appears, as shown in Figure 21-13. Click No.
Notice that the MA briefly says “Running” in the State column of the Management Agents pane.
Notice that the Synchronization Statistics pane in the bottom-lefthand corner displays statistics showing the number of updates and connectors with flow updates. If you click one of the hyperlinks, you can navigate to the information that was loaded.
The Run Step Warning dialog will pop up to annoy you any time you change any of the FIM rules or configuration settings. Even changing (adding, updating, or deleting) files in the Extensions directory will cause this warning to pop up on all run profile executions until every MA undergoes a full synchronization. This is done to force you into reconciling the state of every connector whenever there is a policy change. In this manner, FIM is one of the few Identity Management products that places such a serious emphasis on complete reconciliation and convergence of identity—often at the cost of some performance.
If you ignore the warning, the updates will apply only to connectors processed by the run profile (in our case, only the records we changed). However, the warning will continue to generate FIMSynchronizationService Event ID 6127 Warning messages in the Application Event log until you do so. This is also a cheap but effective method of monitoring for unscheduled changes to your FIM server.
With respect to the telephoneNumber
data that already exists in
the connector space, that data won’t be subjected to those new rules.
The warning is asking whether you’d like to apply the new rules to the
existing objects. Essentially, you ignored the warning because if you
have followed these recipes exactly, you should have only one new object
in the AD MA’s connector space with a telephone number, and that is the
only one that will be synchronized.
Creating a SQL Server Management Agent; Exporting Objects to Active Directory Using an Export Run Profile for exporting objects to AD using an export run profile, which contains information about the confirming import (a Delta Import [Stage Only] step type)
You need to configure and execute an export run profile. First, create the run profile:
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the SQL Server MA.
In the Actions pane on the far-right side, click Configure Run Profiles.
In the “Configure Run Profiles for” pane, click New Profile.
In the Name text box, type Export
and then click Next.
Ensure that Export is selected in the Type drop-down list and then click Next.
Ensure that “default” is showing in the Partition drop-down list and then click Finish.
Click New Step.
In the Configure Step dialog, ensure that Full Import (Stage Only) is selected in the Type drop-down list and then click Next.
Ensure that “default” is selected in the Partition drop-down list and then click Finish.
Ensure that the details in the Step Details field look like Figure 21-14.
Click OK.
You had to select Full Import (Stage Only) for the confirming import step in this run profile because the SQL Server MA hasn’t been configured to provide deltas.
Creating a Run Profile to Export Objects from the AD MA to Active Directory for similarities in how a run profile is configured to export objects to AD
The run profile is configured, but you need to actually move the data from FIM to a SQL Server database.
You need to execute the run profile (refer to (12) in Figure 21-6, which shows the telephoneNumber
data being exported to a SQL
Server database):
Open the Synchronization Service Manager.
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the SQL Server MA.
In the Actions pane on the far-right side, click Run.
In the Run Management Agent dialog, select Export and click OK.
Notice that the MA briefly says “Running” in the State column of the Management Agents pane.
Notice that in the Synchronization Statistics pane in the bottom-lefthand corner, statistics showing the number of updates are displayed.
Now is a good time to add the last two run profiles you created to
the controlling script in Creating a Controlling Script. Then we can make multiple
changes to AD and the SQL Server database and watch the effects by
simply running the script. We could even put a simple loop into the
script so that it is executing continuously and watch new users, deleted
users, and telephoneNumber
change as
they propagate around the systems.
Creating a SQL Server Management Agent; Exporting Objects to Active Directory Using an Export Run Profile for similarities in how a run profile is used to export objects to AD; Creating a Controlling Script
You have started to use FIM, but things aren’t going according to plan. You want to see if the changes you made to either the SQL Server database or AD have made it into the associated connector space.
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the MA you wish to search.
In the Actions pane on the far-right side, click Search Connector Space.
In the Search Connector Space dialog, click the Search button.
You will notice records returned in the main search pane.
If this is the SQL Server MA, the DN of each record will be
the primary key in the database that ensures uniqueness in the
record set. If this is the AD MA, the DN will be the object’s DN in
LDAP format (e.g., cn=Steve
Plank,OU=Users,DC=adatum,DC=com)
.
Record the RDN of a record from the previous step. If it’s the
SQL Server MA, the RDN is the same as the DN. If it’s the AD MA,
it’s the element that contains the least-significant object in the
DN (e.g., cn=Steve Plank
).
Select RDN in the Scope drop-down list.
Type the RDN you have recorded into the text box (e.g.,
cn=Steve Plank
).
Click Search.
You will notice a single record returned, which matches the RDN you have specified.
If you double-click any of the returned records, you can examine the object in detail.
You will see in the Scope drop-down list that there are more entries than just Subtree and RDN. The error collections are useful when trying to debug records that give errors from a large connector space with many thousands of objects in it. We find it particularly useful to use the Pending Export scope to look at outbound changes whenever we are performing a change to a production system. The Pending Export scope allows you to filter additionally by selecting Add, Modify, or Delete to include in the result set. It’s very reassuring to verify that there are no delete operations pending when you make a new change.
Also, once you have double-clicked a record and are viewing its properties, you will notice a Lineage tab at the top of the page. On it, there is a Metaverse Object Properties button. This will show you the properties held on the related metaverse object as well as when the last change was imported from the connected directory. Validating when the last change was seen by FIM can be extremely helpful when troubleshooting why FIM didn’t process a change.
Searching Data in the Metaverse for searching data in the metaverse; MSDN: How to: Find Specified Connector Space Objects
You need to search the metaverse:
Click the Metaverse Search button on the toolbar.
Click the Search button.
Records from the metaverse are returned in the Search Results pane.
Double-click a record in the Search Results pane.
You can see which MA contributed data to this metaverse
object. If you double-click the object that you added a telephoneNumber
to in AD, you should see
its attributes detailed in the pane below the Attributes tab.
Click the Connectors tab.
You can see which MAs this metaverse object is joined to.
The Connectors tab highlights the difference between projection and provisioning. You should see that the link between the metaverse object and the connector space entries was created because of projection rules for the SQL Server MA and provisioning rules for the AD MA. That is because you configured the SQL Server MA to project objects to the metaverse, and then you wrote a rules extension to provision objects from the metaverse to the AD connector space.
Searching Data in the Connector Space for searching data in the connector space; TechNet: Create a Metaverse Search Query
You want to clear out the connector space or the metaverse, perhaps so that you can perform another complete run-through of all these recipes to consolidate learning.
Click the Metaverse Designer button on the toolbar.
In the Actions pane on the far-right side, click Configure Object Deletion Rule.
Ensure that the “Delete metaverse object when connector from this management agent is disconnected” radio button is selected.
Place a checkmark next to the SQL Server MA in the list and then click OK.
Click the Management Agents button on the toolbar.
In the Management Agents pane, click the MA you wish to delete objects from—do the AD MA first.
In the Actions pane on the far-right side, click Delete.
This is important: you risk deleting the whole MA if you do not perform the following step correctly.
Ensure that the “Delete connector space only” radio button is selected.
When prompted that you are sure you want to delete the connector space, click Yes.
A message box will appear with details of how many records were deleted. Click OK.
Perform steps 7–11 again on the HR Database MA.
You configured the metaverse object deletion rule so that when objects from the SQL Server MA were deleted, the related metaverse objects would also be deleted. That is why you deleted objects from the AD MA first. When you performed steps 7–11 the second time, the metaverse objects were also deleted. You can prove this by searching the metaverse in between delete operations.
There is no metaverse delete; FIM ensures that objects in the metaverse always have a join to at least one object in a connector space from at least one MA. The object deletion rule is the configuration that tells FIM what to do with metaverse objects when connector space objects get deleted.
For more control, you can specify that a rules extension should be used to make the decision for you.
It is impossible to end up in the situation where FIM has an object in the metaverse but no corresponding object in any connector space.
You want to add a new attribute to an existing object type in the metaverse so that you can hold data specific to your implementation.
Open the Synchronization Service Manager.
Click the Metaverse Designer button on the toolbar.
In the “Object type” pane, select the object type you wish to
modify (e.g., Person
).
In the lower Actions pane, click the Add Attribute listing.
In the Add Attribute To Object Type dialog box, click the “New attribute” button.
In the New Attribute dialog box, fill in the following properties:
Attribute name (the name of the attribute as you will see it in the metaverse attributes list)
Choosing a nonindexed value will let you store a much larger value here, but it cannot be indexed and should never be used for purposes of a join.
Attribute type (the type of attribute data you can store;
it defaults to String
(indexable)
)
Multi-values (check this if you intend this attribute to be multivalued)
Indexed (check this if you intend the value to be used during join operations)
Click the OK button twice to accept the changes.
Once an attribute is created and attached to an object type, it can be linked to any other object type by following steps 1–4 and then checking off the attribute(s) that you wish to add. Choosing a multivalued attribute type will automatically configure the attribute to also be indexed, if supported by the chosen attribute type.
You want to make changes to one or more flows and you would like to confirm the exact effect the change will have before you roll it out.
The solution involves the use of the Preview function, which is accessed as a property of an individual connector space object:
Open the Synchronization Service Manager.
Locate the connector space object you would like to preview changes against by using the recipe for searching the connector space—you need to pick the connector in the MA that you would run the full or delta synchronization against.
On the Connector Space Object Properties dialog, click the Preview button (see Figure 21-15).
On the Preview dialog, under the “Select preview mode” section, select between a Full Synchronization or a Delta Synchronization; select the radio button accordingly and then click the Generate Preview button (see Figure 21-16).
In the contents pane, you can now browse each step and follow from Source Object Details all the way through provisioning to Export Attribute flow on individual connectors.
Preview is one of the most useful aspects of the FIM product; it allows you to do what if scenarios and ascertain the exact effect any configuration change will have on the state of all identities. Incidentally, the Preview function is actually a side effect of basing FIM on SQL Server. Under normal circumstances, any given run profile step is wrapped in a SQL transaction (one transaction for every connector space object in the MA of the run profile), and as each identity is converged across all connectors, that transaction is committed to the database. In the event of an exception, only that transaction is rolled back and the next identity is processed. Given this feature, the Preview ability simply rolls back the transaction for the given object. This means that FIM is not simply simulating what a run would look like; it’s actually executing the process exactly as it would be under normal circumstances, with the exception that the changes are not committed.
Since Preview is executing every step and rolling back the
transaction, be extremely careful in your rules extensions that you
are not performing actions that can’t be undone. Anything you do
through a rules extension to any source outside of FIM will
not be rolled back because it is outside of the scope of
the SQL transaction. You should use the Utils.InPreviewMode()
property to determine
when you are in Preview mode, and gate certain functions of your
flow.
You want to make changes to a rules extension or flow but you would like to confirm the exact effect the change will have before you roll it out. In addition, you want to commit the changes to only a handful of records that need the changes to go into effect right away and you can’t afford to run a full synchronization to get them.
Locate the connector space object you would like to preview changes against by using the recipe for searching the connector space—you need to pick the connector in the MA that you would run the full or delta synchronization against.
On the Connector Space Object Properties dialog, click the Preview button (see Figure 21-15).
On the Preview dialog, under the Select preview mode section, select between a Full Synchronization or a Delta Synchronization; select the radio button accordingly and then click the Commit Preview button (see Figure 21-16).
In the contents pane, you can now browse each step and follow from Source Object Details all the way through provisioning to Export Attribute flow on individual connectors!
Commit Preview functions like the Preview button; however, it actually commits the transaction at the end for the given connector. This allows you to automatically apply new policies to specific connectors; you should use this strategy only when you absolutely cannot afford (from a time perspective) to run a full sync. Using Commit Preview during testing and certification is recommended when you want to follow a change across data sources.
Searching Data in the Connector Space for searching data in the connector space
You are tracking an event that occurs in an authoritative data source and want to pass a message or a data element to one of the other extensions.
Open Visual Studio and open your rules extension project solution.
You first need to set a transaction property, and while these
properties can be set anywhere, you will most likely set them in
ShouldProjectToMV
, MapAttributesForJoin
, ResolveJoinSearch
, MapAttributesForImport
, MapAttributesForExport
, and Deprovision
, or within the Provisioning
rules extensions. The following example shows two ways of setting
different types of transaction properties:
' String Dim strWF As String = "foobar" Utils.TransactionProperties.Add("WORKFLOW", strWF) ' Boolean Utils.TransactionProperties.Add("DELETE", True)
Once you have one or more properties set, you can query for them elsewhere:
If (Utils.TransactionProperties.Contains("DELETE") AndAlso Utils.TransactionProperties("DELETE").Equals(True)) Then ' This allows for a typesafe way to query for the existence of a property End If If (Utils.TransactionProperties.Contains("WORKFLOW") AndAlso Utils.TransactionProperties("WORKFLOW").ToString.Contains("foo")) Then ' This allows you to search the contents of a string property ' You can then do an assignment Dim strWFResponse As String =↵ Utils.TransactionProperties("WORKFLOW").ToString End If If (Utils.TransactionProperties.Contains("WORKFLOW") AndAlso Utils.TransactionProperties("WORKFLOW").Equals("foobar")) Then ' This allows you to do a simple comparison End If
A transaction property is only good for as long as the current FIM transaction is running. This makes it relevant only to the identity you are processing, and it is available across all extensions that are touched as part of the synchronization of that identity; when the next identity is loaded for processing, all transaction properties are destroyed.
You have several attributes that you would like to apply the same
block of code to, and you don’t want to duplicate the same block of code
or call the same function from multiple case
statements.
Open Visual Studio and open your rules extension project solution.
Add a code block similar to this (before your main select case FlowRuleName
statement):
If FlowRuleName.StartsWith("Trim:") Then ' Trim String ' ' Reusable code to convert an attribute to its string format ' FlowRuleName will be passed as "Trim:srcAttribute,destAttribute" ' Dim strAttributeName, strSrcAttribute, strDestAttribute, arrAttribs() As String ' Replace the beginning of the flowrulename with nothing strAttributeName = FlowRuleName.Replace("Trim:", "") arrAttribs = strAttributeName.Split(","c) ' Splits the string ' on a comma trSrcAttribute = arrAttribs(0) ' Assigns the first value strDestAttribute = arrAttribs(1) ' Assigns the second value ' Now we can assign the value and trim any whitespace at the front and back mventry(strDestAttribute).Value = csentry(strSrcAttribute).Value.ToString.Trim Else If FlowRuleName.StartsWith("MyFunction:") Then ' Apply custom function ' ' Reusable code to apply a custom function to an attribute ' FlowRuleName will be passed as "MyFunction:sourceAttribute,destinationAttribute" ' Dim strAttributeName, strSrcAttribute, strDestAttribute, arrAttribs() As String ' Replace the beginning of the flowrulename with nothing strAttributeName = FlowRuleName.Replace("MyFunction:", "") arrAttribs = strAttributeName.Split(","c) ' Splits the string on a comma strSrcAttribute = arrAttribs(0) ' Assigns the first value strDestAttribute = arrAttribs(1) ' Assigns the second value ' Now we can apply your custom function prior to the assignment Dim strSrcAttributeValue As String strSrcAttributeValue = MySharedCodeLib.MyFunction(csentry(strSrcAttribute).Value) mventry(strDestAttribute).Value = strSrcAttributeValue Else ' Continue on as you normally do Select case FlowRuleName
Open the Synchronization Service Manager.
Apply the rule.
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the AD MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “user” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the Mapping Type section of the dialog, select Advanced.
In the Flow Direction section of the dialog, select Export and then check the box to Allow Nulls.
If you don’t check the box to Allow Nulls, the rule value will never be contributed.
Select telephoneNumber
from
the data source attributes list.
Select <object-id>
from the
Metaverse attributes list.
Selecting <object-id>
here
ensures that the source value will always be present; otherwise, the
rule will not fire if the source value in the metaverse is null
.
Click New.
In the Advanced Export Attribute Flow Options dialog, type
Delete:telephoneNumber
.
Open Visual Studio and open your rules extension project solution.
If you are using Using a Single Rules Extension to Affect Multiple Attribute
Flows, insert the
following before the final Else
;
otherwise, only the final line is needed in a standard Case
block:
Else If FlowRuleName.StartsWith("Delete") Then ' ' Reusable code to delete the referenced attribute ' FlowRuleName will be passed as "Delete:Attribute" ' Dim strAttributeName As String ' Replace the beginning of the flowrulename with nothing ' to find the attribute to be deleted strAttributeName = FlowRuleName.Replace("Delete:", "") ' This is whre we delete the value csentry(strAttributeName).Delete()
You never have to actually set a “null value” to contribute a
delete to another data source. This is partially due to the fact that
different systems handle null values differently and in order to
contribute the proper value, the Delete()
property is used to handle that
translation for you.
To process any Advanced Rules extension, you need to have a value
in the source attribute. A common problem occurs when the source
attribute is null in the metaverse, preventing the rule from firing on
that identity. An advanced flow will fire if an existing value is
deleted (by contributing a null), but it will never fire if the value is
null to begin with. In addition, while using a fixed value like
<object-id>
ensures that the value will
never be null, this value will never change and therefore you will
require a full synchronization run to trigger this rule; however, you
can use Committing Changes to Individual Identities Using the Commit
Preview Feature to
force a full synchronization on an individual identity and commit the
changes.
You want to import the accountExpires
attribute into the metaverse as
a string-formatted date/time value. This could be any of the Large
Integer/Interval syntax attributes, such as accountExpires
, badPasswordTime
, lastLogoff
, lastLogon
, lastLogonTimestamp
, lockoutTime
, or pwdLastSet
.
See Extending Object Types to Include a New Attribute to add a new metaverse attribute if necessary.
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the AD MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “user” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the Mapping Type section of the dialog, select Advanced.
In the Flow Direction section of the dialog, select Import.
Select accountExpires
from
the data source attributes list.
Select the attribute created in step 2 or an existing String
attribute from the Metaverse
attributes list (e.g., AccountExpirationDate
).
In the Advanced Import Attribute Flow Options dialog, type
ConvertFileTime:accountExpires,AccountExpirationDate
,
and then click OK twice.
Open Visual Studio and open your rules extension project solution.
If you are using Using a Single Rules Extension to Affect Multiple Attribute
Flows insert the
following before the final Else
;
otherwise, only the final line is needed in a standard Case
block:
ElseIf FlowRuleName.StartsWith("ConvertFileTime:") Then ' ' Reusable code to convert generalized time into string format ' FlowRuleName will be passed as "ConvertFileTime:sourceAttribute,destinationAttribute" ' Dim strAttributeName, strSourceAttribute, strDestinationAttribute,↵ arrAttribs() As String ' Replace the beginning of the flowrulename with nothing to find↵ the attribute to be deleted strAttributeName = FlowRuleName.Replace("ConvertFileTime:", "") arrAttribs = strAttributeName.Split(","c) strSourceAttribute = arrAttribs(0) strDestinationAttribute = arrAttribs(1) ' NOTE: The value will be invalid if it was never set ' (9223372036854775807 (0x7FFFFFFFFFFFFFFF)) ' or 0 if it was set and then later cleared Const AD_ACCOUNT_NO_EXPIRATION As Long = 9223372036854775807 If (strSourceAttribute = "accountExpires") Then If (csentry(strSourceAttribute).Value = 0 OrElse csentry(strSourceAttribute).Value = AD_ACCOUNT_NO_EXPIRATION) Then ' The value was cleared or never set mventry(strDestinationAttribute).Value = "Never" Else ' The value has been set Dim dtFileTime As DateTime = DateTime.FromFileTime(DateTime.Parse(csentry↵ (strSourceAttribute).Value).ToFileTme) mventry(strDestinationAttribute).Value = Format(dtFileTime, "yyyy-MM-dd") End If Else ' We are not dealing with the accountExpires attribute, just decode it Dim dtFileTime As DateTime = DateTime.FromFileTime(DateTime.Parse(csentry(strSourceAttribute).Value)↵ .ToFileTime) mventry(strDestinationAttribute).Value = Format(dtFileTime, "yyyy-MM-dd") End If
The Large Integer/Interval syntax in Active Directory can be
decoded by using the DateTime.FromFileTime()
function in the .NET
Framework. By using the DateTime.Parse().ToFileTime
property, you are
ensuring that the value you are getting is a valid date/time.
If you are concerned with data integrity here, consider wrapping
this in a Try
/Catch
block.
You want to export to the accountExpires
attribute from a
string-formatted date/time value in the metaverse. This could be any of
the Large Integer/Interval syntax attributes, such as accountExpires
, badPasswordTime
, lastLogoff
, lastLogon
, lastLogonTimestamp
, lockoutTime
, or pwdLastSet
.
Open the Synchronization Service Manager.
Click the Management Agents button on the toolbar.
In the Management Agents pane, double-click the AD MA.
In the Management Agent Designer pane on the lefthand side, select Configure Attribute Flow.
Ensure that “user” is selected in the data source object type drop-down list.
Ensure that “person” is selected in the metaverse object type drop-down list.
In the Mapping Type section of the dialog, select Advanced.
In the Flow Direction section of the dialog, select Export.
Select accountExpires
from
the data source attributes list.
Select an existing String attribute from the Metaverse
attributes list (e.g., Account
ExpirationDate
).
In the Advanced Export Attribute Flow Options dialog, type
ConvertFileTime:accountExpires,AccountExpirationDate
,
and then click OK twice.
Open Visual Studio and open your rules extension project solution.
If you are using Using a Single Rules Extension to Affect Multiple Attribute
Flows, insert the
following before the final Else
;
otherwise, only the final line is needed in a standard Case
block:
ElseIf FlowRuleName.StartsWith("ConvertFileTime:") Then ' ' Reusable code to convert generalized time into string format ' FlowRuleName will be passed as "ConvertFileTime:sourceAttribute,destinationAttribute" ' Dim strAttributeName, strSourceAttribute, strDestinationAttribute,↵ arrAttribs() As String ' Replace the beginning of the flowrulename with nothing to find↵ the attribute to be deleted strAttributeName = FlowRuleName.Replace("ConvertFileTime:", "") arrAttribs = strAttributeName.Split(","c) strSourceAttribute = arrAttribs(0) strDestinationAttribute = arrAttribs(1) ' NOTE: The value will be invalid if it was never set ' (9223372036854775807 (0x7FFFFFFFFFFFFFFF)) ' or 0 if it was set and then later cleared Const AD_ACCOUNT_NO_EXPIRATION As Long = 9223372036854775807 If (strDestinationAttribute = "accountExpires") Then If (mventry(strSourceAttribute).IsPresent = False) Then ' The value in the metaverse is empty so remove the account expiration csentry(strDestinationAttribute).IntegerValue = 0 Else ' We should have a date value present to enforce Dim dtFileTime As DateTime = DateTime.Parse(mventry(strSourceAttribute).Value) csentry(strDestinationAttribute).IntegerValue = dtFileTime.ToFileTimeUtc() End If Else ' We are not dealing with the accountExpires attribute,↵ just encode it Dim dtFileTime As DateTime = DateTime.Parse(mventry(strSourceAttribute).Value) csentry(strDestinationAttribute).IntegerValue =↵ dtFileTime.ToFileTimeUtc() End If
The Large Integer/Interval syntax in Active Directory can be
encoded by using the DateTime.ToFileTime()
function in the .NET
Framework. By using the DateTime.Parse()
property, you are ensuring
that the value you are getting is a valid date/time.
If you are concerned with data integrity here, consider wrapping
this in a Try
/Catch
block.
18.191.39.181