Adding and removing the same value from a multivalued property

For some reason I had assumed that I wouldn’t be able to remove and re-add the same value to a multivalued property in the same request – but it turns out you can – and it helped me greatly simplify a script, so hooray for that!

So why did I want to do this anyway?

I’m doing a service request design where people need entitlement objects to allow the appropriate service role to be linked to their profile. In case of any workflow failures or other weirdness I want a script to run periodically and just check everything’s lined up.

I was mucking around with trying to compare entitlements to linked roles – but when I realised I can just remove all the current roles and re-add the ones I need in the same request it made the script a lot simpler.

I then just need to add a count to check there actually are changes to upload – no point flooding the FIM service with requests that remove and re-add exactly the same values – and my script is done.

Here’s the script. It uses the FIMPowerShell Function library from http://technet.microsoft.com/en-us/library/ff720152(v=ws.10).aspx

PARAM($Filter)
### 
### Review-Entitlements.ps1
###
### Run overnight to confirm that people's service-roles match their entitlements.
### Can be broken down by XPath filter to reduce the size of the query.
###

. E:\scripts\functions.ps1

if (-not $Filter) {$Filter = "/Person"}

## Get all people according to the filter
$People = Export-FIMConfig -CustomConfig $Filter -OnlyBaseResources

foreach ($person in $People)
{
    $PersonID = ($person.ResourceManagementObject.ObjectIdentifier).Replace("urn:uuid:","")

    $Changes = New-Object System.Collections.ArrayList  # Keeps track of the number of changes so we don't run unnecessary requests

    $ImportObject = ModifyImportObject -TargetIdentifier $PersonID -ObjectType "Person"

    $CurrentRoles = ($person.ResourceManagementObject.ResourceManagementAttributes | where {$_.AttributeName -eq 'Applications'}).Values
    if ($CurrentRoles) {foreach ($role in $CurrentRoles)
    {
        RemoveMultiValue -ImportObject $ImportObject -AttributeName "Applications" -NewAttributeValue $role
        $Changes.Add($role)
    }}

    $Filter = "/Entitlement[PersonLink='" + $PersonID + "' and " +
                "ExpirationTime > op:subtract-dayTimeDuration-from-dateTime(fn:current-dateTime(), xs:dayTimeDuration('P1D')) and " +
                "StartDate < fn:current-dateTime() and " +
                "RoleAttribute = 'Applications'" +
                "]"
    $Entitlements = Export-FIMConfig -CustomConfig $Filter -OnlyBaseResources
    if ($Entitlements) {foreach ($ent in $Entitlements)
    {
        $role = ($ent.ResourceManagementObject.ResourceManagementAttributes | where {$_.AttributeName -eq 'RoleLink'}).Value
        AddMultiValue -ImportObject $ImportObject -AttributeName "Applications" -NewAttributeValue $role
        if ($Changes.Contains($role)) {$Changes.Remove($role)}
        else {$Changes.Add($role)}
    }}

    if ($Changes.Count -gt 0) {Import-FIMConfig $ImportObject}
}

 

2 Replies to “Adding and removing the same value from a multivalued property”

  1. Nice. Would be nice however if we had timers that could be set in the FIM Service instead that would allow us to do these kinda checks / workflows within the service periodically instead having external jobs

Leave a Reply

Your email address will not be published. Required fields are marked *


*