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} } Â
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
Have you seen Bob’s stuff on a housekeeping policy? He uses temporal sets and a WF to toggle MPRs so that ROPU WF get triggered. I’m probably going to use some of these concepts in my current project, but at the moment just powershelling everything because it’s easier in the design phase. https://unifysolutions.jira.com/wiki/display/FIMTEAMCOM/Designing+and+scheduling+Housekeeping+policy+entirely+within+the+FIM+Portal