FIM2010R2–Adding “Filter” attribute to Custom Objects

During a recent engagement, I was looking to add the “Filter” attribute to a custom object in the FIM Service. I used the “Filter” attribute because of the recommendation provided by the “Resource Control Display Configuration XML Reference” for the UocFilterBuilder control.

When the control was added, I kept getting errors that the request had “Failed”. The event viewer had a cryptic error about a “FOREIGN KEY constraint” that had occurred in the FIM Service database.

Turns out that another blog post pointed me in the right direction. In this post, the “Domain” attribute was added to a custom object and a failure and error message was generated. The root cause was that the “DomainConfiguration” was not also bound to the object because the Domain attribute and DomainConfiguration attributes are paired together in the underlying data structure and you can’t have one without the other apparently.

Turns out for that a “Filter” attribute will require that you add the “Temporal” attribute to the object. I also added ComputedMember as well for good measure and everything started to work normally.

I did not test whether or not pushing the filter builder control output to another text attribute would remove the dependency issue.

Posted in Forefront Identity Manager 2010 | Leave a comment

FIM2010–Creating a Group Membership Tab in a User RCDC

I have to admit, I was working on a demo and I wanted to add a group membership tab into my RCDC. As always, I started by doing a search to see if anyone had posted something about this before. Carol, of missmiis fame and FIM MVP, had already posted a sample of the UocListView control for this type of feature here. (Thanks Carol!)

I used her control and modified it a bit to create a tab to add into my RCDC. As part of the tab, I wanted to create one list for the explicit membership and another for the calculated (or dynamic) memberships.  The final output of the RCDC looks like:

GroupMembershipTab

It was interesting to note that the calculated membership attribute contained both dynamic as well as explicit memberships. The filter for the dynamic memberships had to be modified to actually exclude any groups where the explicit membership was granted. This filter looked like:

/Group[(ComputedMember=’%ObjectID%’) and not (ExplicitMember=’%ObjectID%’)]

The explicit group filter, as I’m sure you can imagine, is a direct search with

/Group[(ExplicitMember=’%ObjectID%’)]

Anyway, if you’re interested to add the group membership tab to your user RCDC, the code follows:

<my:Grouping my:Name=”groupMemberships” my:Caption=”Group Memberships” my:Enabled=”true” my:Visible=”true”>
    <my:Control my:Name=”ExplicitMemberships” my:TypeName=”UocListView” my:ExpandArea=”true” my:Caption=”Explicit Group Memberships”>
    <my:Properties>
      <my:Property my:Name=”ColumnsToDisplay” my:Value=”DisplayName,Type,Email,Domain” />
      <my:Property my:Name=”EmptyResultText” my:Value=”There are no groups according to the filter definition.” />
      <my:Property my:Name=”PageSize” my:Value=”20″ />
      <my:Property my:Name=”ShowTitleBar” my:Value=”true” />
      <my:Property my:Name=”ShowActionBar” my:Value=”false” />
      <my:Property my:Name=”ShowPreview” my:Value=”false” />
      <my:Property my:Name=”ShowSearchControl” my:Value=”false” />
      <my:Property my:Name=”EnableSelection” my:Value=”false” />
      <my:Property my:Name=”SingleSelection” my:Value=”false” />
      <my:Property my:Name=”ItemClickBehavior” my:Value=” ModelessDialog ” />
      <my:Property my:Name=”ListFilter” my:Value=”/Group[(ExplicitMember=’%ObjectID%’)]” />
    </my:Properties>
  </my:Control>
  <my:Control my:Name=”CalculatedGroupMemberships” my:TypeName=”UocListView” my:ExpandArea=”true” my:Caption=”Calculated Group Memberships”>
    <my:Properties>
      <my:Property my:Name=”ColumnsToDisplay” my:Value=”DisplayName,Type,Email,Domain” />
      <my:Property my:Name=”EmptyResultText” my:Value=”There are no groups according to the filter definition.” />
      <my:Property my:Name=”PageSize” my:Value=”20″ />
      <my:Property my:Name=”ShowTitleBar” my:Value=”true” />
      <my:Property my:Name=”ShowActionBar” my:Value=”false” />
      <my:Property my:Name=”ShowPreview” my:Value=”false” />
      <my:Property my:Name=”ShowSearchControl” my:Value=”false” />
      <my:Property my:Name=”EnableSelection” my:Value=”false” />
      <my:Property my:Name=”SingleSelection” my:Value=”false” />
      <my:Property my:Name=”ItemClickBehavior” my:Value=” ModelessDialog ” />
      <my:Property my:Name=”ListFilter” my:Value=”/Group[(ComputedMember=’%ObjectID%’) and not (ExplicitMember=’%ObjectID%’)]” />
    </my:Properties>
  </my:Control>
</my:Grouping>

Posted in Uncategorized | Leave a comment

FIM2010–Removing a Pending Deletion from a Datasource

Recently I was working on testing some code with my team and we realized that there were unexpected deletes occurring in the connector space for the Active Directory MA. The problem was these accounts shouldn’t be deleted and therefore, we had to figure out a way to stop these deletes without clearing and reloading the connector spaces of the systems.

The problem is that when an object is slated as a pending deletion export, the connector is changed to an explicit disconnector. Even if you run the MA to reload the object in, the system continues to consider it a pending deletion on the next export run. To prevent the delete from occuring and reattach it to the metaverse entry on which it belongs, the following tasks need to be completed:

  1. Ensure that the metaverse object is still present.
    1. If the object was deleted in the metaverse, you will have to first synchronize the object so the object is present. You may need to turn off provisioning code for this to work properly and you also may just want to use preview to “surgically” add the deleted object back to the metaverse.
    2. If the object was present,  make sure all the data required for joining is present.
  2. Go to the “Joiner” tool and find the object in the explicit disconnectors.
  3. Change the object from an explicit disconnector back to a normal disconnector.
  4. Use preview mode on the disconnector to join it back to the metaverse object. (Note that I do not generally use the joiner tool to perform the join because I like to avoid having explict connectors in my systems.)
  5. Find the metaverse entry for the object using the “Metaverse Search” tool.
  6. Open the properties of the entry and look at the lineage to make sure the previously “disconnected” system is connected.
  7. Double click on the connector space entry that was to be deleted and make sure that it is no longer a pending deletion.

There are a few steps involved but really only steps 2 through 5 are actually fixing the entry. The other steps are preparation and validation. Nothing worse than having administrators complaining because entries were deleted and they had to clean it up. Smile

Posted in Forefront Identity Manager 2010 | Leave a comment

A Question of Attestation

I have been in and out of a lot of clients where there is much discussion about attestation. The question is, how do they define attestation and how does it apply to their needs? In many cases, I am seeing solutions that are more complex than may actually be required in practice.

A friend of mine, who is working as an auditor, told me that basically an auditor is responsible to hold one to their own standards and policies. Granted, this is true but omits the fact that the policies and controls must cover the appropriate governance requirements of the industry you are in (whether this be SOX, HIPAA, or other relevant policy requiring regular review of user access).

So, that said, what defines attestation for your organization is the first question you should ask before embarking on a large scale attestation and compliance project? Do you need to have ever user in a group attested to individually which is what the BHold and Omada suites have you do or can you simply have the group owner say that he reviewed the membership and check a box and record when he did that?

This is an important question to ask. In many organizations there are more groups than there are users. In those same organizations, there are few people who actually own or maintain groups and attesting to every member in every group is almost a full time job.

What if one of their groups contains 1000 people? Can you imagine having to click 1000 times to attest that all these users are certified for that access? If your audit policy demands it, then go for it, but I would suggest some secondary strategies for making it work.

1. Divide access groups into sub-groups that will allow you to share the attestation among many people. If the group is across business units, why have someone in the business unit who owns the app primarily responsible for the access? Can the supervisors in the other business units attest to their peoples need to be in the group? If yes, nest a group that can have the attestation delegated.

2. Can you share attestation tasks with multiple users from the application owners business unit? Instead of having one group owner, can you have multiple owners who share responsibility for doing the 1000 clicks? One owner responsible for people who have last names starting with A – M for example and the other taking care of the rest (granted that example is still a staggering 500 clicks per owner, but still better than 500 in my opinion!)

Attestation strategies can be creative. So long as they meet the requirement for the level of compliance you need to attain, you do not have to think fine grained attestation. You may be able to use something much simpler.

Posted in Random IdM Musings | Leave a comment

FIM2010–Getting Accurate Run Statistics using WMI

I was recently working on an email body that was being sent to a client when his sync schedule ran during the day. The run script that I had created captured the statistics that the WMI object provided. So, I had the following basic code (lines numbered for clarity):

  1. $miisWmiObject = get-WMIObject – class MIIS_ManagementAgent – namespace root/MicrosoftIdentityIntegrationServer – filter “Name=”Text Management Agent”
  2. $MiisWmiObject.Execute(“Full Import”)
  3. [int] $add = $MiisWmiObject.NumImportAdd().ReturnValue
  4. [int]$mod = $MiisWmiObject.NumImportUpdate().ReturnValue
  5. [int]$del = $MiisWmiObject.NumImportDelete().ReturnValue

(Then there were lines of code to put the values in the file in a nice and neat manner.)

The email body had there being 196 adds, 2 modifies and 0 deleted. This was strange because the operations log showed that no changes had been made at all. It was all zeros across the board. Where did these numbers come from?

On closer inspection, the statistics actually reflect the pending imports or connectors that have not yet been connected to the metaverse. Looking at the connector space of the MA showed that there were 196 pending import additions and 2 pending import modifications.

Well, those values are not what I need to report on. I need to actual statistics as being shown by the operations tab of the screen. That is when I found the “RunDetails()” method that is part of the “MIIS_ManagementAgent class. This returns the full run details in xml format (see this link for an example of the format –> http://msdn.microsoft.com/en-us/library/windows/desktop/ms698398(v=vs.100).aspx). Ah ha! I could drill down into the XML returned by that command to find my information.

To get the staging statistics, the following code was required (modified the code up top so you can see the changes):

  1. $miisWmiObject = get-WMIObject – class MIIS_ManagementAgent – namespace root/MicrosoftIdentityIntegrationServer – filter “Name=”Text Management Agent”
  2. $MiisWmiObject.Execute(“Full Import”)
  3. [xml]$runHistory = $MiisWmiObject.RunDetails().ReturnValue
  4. $stagingStats = $runHistory.’run-history’.’run-details’.’step-details’.’staging-counters’
  5. [int] $add = $stagingStats.’stage-add’.’#text’
  6. [int]$mod = $stagingStats.’stage-update’.’#text’
  7. [int]$del = $stagingStats.’stage-delete’.’#text’
  8. [int]$nochange = $stagingStats.’stage-no-change’.’#text’

Note that on line 3, you have to cast the “ReturnValue” into XML. Otherwise, it is parsed as a string and the commands will not work. Also, all the nodes with the “-“ and “#” characters have to be surrounded by the single quote or PowerShell will not parse it and you’ll get one of the red-errors of death.

I was also happy to show that I could return the total of entries that were not modified as well (line 8) as that made the report even more completed.

There are other nodes in the xml that you can use. I also used the “export-counters” node to get the different export statistics. Replace the “staging-counters” with export counts in line 4 of the second block of code to get these counters. It includes nodes with information for export-add, export-update, export-rename, export-delete, export-failure and export-delete-add.

Posted in Forefront Identity Manager 2010 | Leave a comment

FIM2010–Sync Engine Oddities

The other day I was working with a coworker and doing some previews of objects that were going through a change of state. The state change from the data source involves a new record being added and an old record being deleted. So it has a pretty major impact because the anchor changes with a delete that wants to remove a metaverse object and an add that wants to project a new object.

In the code, there is a defined connector filter that checks to see if the object is connected or not, and if it is not, see if there is an object with the same account name present in the metaverse. The join rules allow the entries to join on the account name values so if one is disconnected, it can be rejoined (convergence strategy).

On the import, the first record was deleted and the second record was added. The records had the same account name information. The preview of the added record makes it by the connector filter, but fails on the join rule because of ambiguous attribute flows. This would indicate that the metaverse search that was run in the connector filter did not find the entry that the join rules did. Was this because the object in the CS was deleted on the import? If so, why did the join rule find the entry and try to join?

This led me further down the path of running a synchronization. Unlike the import of the data in a text-based MA, the synchronization processed the deletions first. So in this case, the added entry projected because the MVObjectDeletion rules took the object out of the system. (Admittedly, this was undesired behavior as well but something that is being mitigated by some modifications to how the MVObjectDeletion rule operates, but it does illustrate how the preview function may provide false negatives on an action because an operation that would happen beforehand during normal operations has not been executed).

Long story short, preview is a tool. It is not infallible and does require that you review how the objects are processed. Errors in the tool may or may not be reflected through normal synchronization processes.

Posted in Forefront Identity Manager 2010 | Leave a comment

Apologies!

Hi All,

Sorry that I have fallen out of the blogosphere for a while. I have been going through a lot of changes in life including preparing for and getting married to my best friend, Michelle. Now that things have started to settle down I will work on getting together some posts for  on the things I’ve experienced and any workarounds found.

Hope all is well for everyone out there.

Thanks

B

Posted in Uncategorized | 2 Comments