Introduction

With Forefront Identity Manager 2010 R2 Microsoft add some performance modifications to Service and Portal. By default exports from the FIM Management Agent are batched (aggregated) up to 1000 changes. So in request details you may see only an Update to msidmCompositeType ?? Request which includes all the changes of maybe multiple objects in the RequestParameter attribute.

Since this is very good for performance on exports, it is very bad for searching changes in the request log in portal. In my environment I even see changes that seems to be only relevant to one object, holding changes to multiple objects. In this particular case the requests display name is Update to msidmCompositeType ?myuser? Request, but in the RequestParameter attribute I also found changes to other objects.


Requirements

The script is based on the FIMAutomation snap-in and also the FIM PowerShell Module from Craig and Brian. Because I missed some attribute in the output of the Get-FIMRequestParameter cmdlet I have modified it a little bit.

To use this script you must in addition to install the FIMPowerShellModule, modify the FIMPowerShellModule.psm1 file like below. I?ve only added the Mode and Target properties to the output of the Get-FIMRequestParameter function.

$RequestParameter | foreach-Object{
    New-Object PSObject -Property @{
        Mode = ([xml]$_).RequestParameter.Mode
         Target = ([xml]$_).RequestParameter.Target
        PropertyName = ([xml]$_).RequestParameter.PropertyName
        Value = ([xml]$_).RequestParameter.Value.'#text'
        Operation = ([xml]$_).RequestParameter.Operation
     } |
     Write-Output

 


How to search for request details

Normally you can search the request details by parsing the XML data in the RequestParameter attribute of a request object like this:

$Export=Export-FIMConfig ?only ?custom ?/Request[Target=/Person[AccountName=?stapf?]]?

You can then get the RequestParameter attribute as an XML document and use it like you need. Because the msidmCompositeType object can hold changes of more than one object you have to get this details a little bit different, like this:

$Export=Export-FIMConfig ?only ?custom ?/Request[Target=/msidmCompositeType[/msidmElement=/Person[AccountName=?stapf?]]]?

You will get all batched requests that are relevant to the person object you search for, but this request objects has also the changes for many other objects in its RequestParameter attribute. But there is hope, as the RequestParameter attribute also contains the target object GUID in its XML data, so you can filter out only the relevant changes.


The script and what it does

While you cannot actually searching the request log for changes to a specific object, especially with the new batch object type, I?ve decided to create a little script for this, in PowerShell of course. Giving an objectType, attribute and value to search, the script will retrieve all changes to this object searching all direct/single requests and also all batched updates.

param($objectType, $attribute, $searchValue)
#objectType = The objectType of the target object you are trying to get requests for.
#attribute = The attribute of the target object you want to use for searching
#searchValue = The value of the attribute of the target object you are searching requests for
#
#ex. Get-FIMRequestDetails.ps1 -objectType "Person" -attribute "AccountName" -searchValue "pstapf"
#
#This gets all requests matching the given target object.
  
# Load FIMAutomation SnapIn and FIMPowershellModule (http://fimpowershellmodule.codeplex.com)
if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {add-pssnapin FIMAutomation}
Import-Module C:\Windows\System32\WindowsPowerShell\V1.0\Modules\FIM\FIMPowerShellModule.psm1
  
# Check if the object you are searching requests for exists in portal and get its GUID
$filter = "/" + $objectType + "[" + $attribute + "=" + $searchValue + "]"
$searchObject = Export-FIMConfig -OnlyBaseResources -CustomConfig $filter
  
If ($searchObject -ne $null)
{
    $searchObjectGuid = $searchObject.ResourceManagementObject.ObjectIdentifier.Replace("urn:uuid:","")
    Write-Host "Object found:" $searchValue " with GUID:" $searchObjectGuid
}
else
{
    Write-Host "The object you are searching for does not exists in FIM Portal"
    Exit
}
  
# Get the aggregated requests of the object you search for
$export=@()
$filter = "/Request[Target=/msidmCompositeType[/msidmElement=/" + $objectType + "[" + $attribute + "=" + $searchValue + "]]]"
$export = Export-FIMConfig -OnlyBaseResources -CustomConfig $filter
  
# Get the single requests of the object you search for
$filter = "/Request[Target=/" + $objectType + "[" + $attribute + "=" + $searchValue + "]]"
$export += Export-FIMConfig -OnlyBaseResources -CustomConfig $filter
$requestlist = $export | Convert-FimExportToPSObject | Sort-Object msidmCompletedTime
  
# Get the RequestParameter of the object you search fo from all requests and add some requestDetails
If ($requestlist.count -gt 0)
{
    $resultItems = @()
    foreach ($requestItem in $requestList)
    {
        $resultItems += $requestItem | Get-FimRequestParameter | where { $_.Target -eq $searchObjectGuid } | ForEach-Object {
        New-Object PSObject -Property @{
            Target = $_.Target
            Operation = $_.Operation
            Mode = $_.Mode
            Attribute = $_.PropertyName
            Value = $_.Value
            RequestName = $requestItem.DisplayName
            RequestGuid = $requestItem.ObjectID.Replace("urn:uuid:","")
            CompleteTime = $requestItem.msidmCompletedTime
            Status = $requestItem.RequestStatus
            }
        }
    }
    $resultItems
  
}
else
{
    Write-Host "No request found for the object you searched for."
}

Additional Notes

Script output is PSObject, so you can pipe the output to many other cmdlets, like Out-GridView or Convertto-Html for example. In addition you can filter the output by date also on your own. Out-GridView is a very neat cmdlet for this, as you can show/hide columns and also do some basic filtering, try a Status:Completed filter for example.

Here is also some output with ConverTo-Html using some basic CSS:


Additional Resources

My original article on my blog: JustIDM.wordpress.com