Jun 25, 2014 11:56:00 AM
Batch Attribute Updates for Users in Forefront Identity Manager (FIM)

A client recently requested the ability to use data in an externally-generated file to perform batch attribute updates for Users in the FIM Service. What made this more complicated than expected was that some of the user attributes, for example Manager, were FIM references.

In a simple case, say the Title attribute, we could just set the attribute to the new value in PowerShell and update using the FIM Automation snap-in. For a reference attribute, though, we’d have to literally look up the GUID of the referenced object in the FIM Portal, copy that into the source data file and then perform the simple update.

To make life easier for the client, we implemented an XPath lookup for those attributes that were known references, so that they could use an easier way of identifying the referenced value, say their AD account name.

The example below is considerably simplified to show just the process for updating the User’s Manager attribute. The original client code is more complex, but adds very little to what’s illustrated here.

We’ll start with initializing the FIM Automation snap-in and a variable to reference the FIM web service. For demonstration purposes, just use simple variables to represent our User, attribute name and attribute value:

<i># Loads the FIM PS tools if not already loaded</i>
<b>if</b> (@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {Add-PSSnapIn FIMAutomation}
<i># Sets basic script variables for location of FIM service and CSV file</i>
Set-Variable -name URI -value <a href="http://localhost:5725/resourcemanagementservice">http://localhost:5725/resourcemanagementservice</a>
<i># Static parameters for demonstration</i>
$userAccountName = "JohnDoe"
$userAttributeName = "Manager"
$userAttributeValue = "JohnsManager"

After initialization, we’ll use export-fimconfig and an XPath expression to retrieve the User’s account object. This returns a FIM Person object and is used to create the ImportObject for use with the FIM web service:

 $userObject = export-fimconfig -uri $URI -onlyBaseResources  -customconfig
    "/Person[AccountName='$userAccountName']"
<b>if</b>($user -eq $null) {
    throw "Cannot Get User by AccountName=$userAccountName"
}
 $importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
$importObject.ObjectType = "Person"
$importObject.SourceObjectIdentifier =
    $userObject.ResourceManagementObject.ObjectIdentifier
$importObject.TargetObjectIdentifier =
    $userObject.ResourceManagementObject.ObjectIdentifier
$importObject.State = 1

Next we use the provided Manager’s textual account name and retrieve the Person object. That PowerShell reference is then formatted to a simple GUID:

$managerObject = export-fimconfig -uri $URI -onlyBaseResources  -customconfig
    "/Person[AccountName='$userAttributeValue']"
 <b>if</b>($user -eq $null) {
    throw "Cannot Get User by accountName=$accountName"
}
 $managerObject = $managerObject.ResourceManagementObject.ObjectIdentifier
    -replace "urn:uuid:",""

Once we have the GUID for the User’s manager, we can create a new ImportChange object, add the new reference and attribute name to that and then add that to the original ImportObject.

Finally Import-FIMConfig can be used to send the result to the FIM web service:

$importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange
$importChange.Operation = 1
$importChange.AttributeName = $userAttributeName
$importChange.AttributeValue = $userAttributeValue
$importChange.FullyResolved = 1
$importChange.Locale = "Invariant"
 $importObject.Changes = $importChange
 $importObject | Import-FIMConfig

All of which makes for a simple way to enable an end-user to transparently work with FIM references.