none
Uploading photos to AD and Allowing Users to Change Their Photo RRS feed

  • Question

  • Hello,

    I have a requirement to load photos from FIM into AD and have a couple of questions:

    If I can get Soren's MA working, then the following blog post should work nicely for a file based upload.

    http://www.iamblogg.com/2013/04/14/import-pictures-into-fim-portal/

    However, once in FIM, can I sync photos to AD using declarative/codeless sync rules?

    Secondly, within the FIM portal, is it straight forward to give users the ability to upload\edit their own pictures (and subsequently sync these with AD)?

    Cheers


    IT Support/Everything

    Wednesday, September 4, 2013 9:51 AM

All replies

  • However, once in FIM, can I sync photos to AD using declarative/codeless sync rules?

    It's like any other attribute. You have to create one flow to metaverse (in FIM MA) and then one flow in your AD synchronization rule.

    Secondly, within the FIM portal, is it straight forward to give users the ability to upload\edit their own pictures (and subsequently sync these with AD)?

    Again, it's like any other attribute. Just use MPR to grant them right to edit it.
    Wednesday, September 4, 2013 10:53 AM
  • Hello,

    i did nearly the same in the solution of our customer.

    Via TaskScheduler a Powershell Script pull jpg photos from a share into the FIM Portal using the FIMAutomation Cmdlets.

    (We load the jpg into an bytearray and do an Base64 Encode)

    Then the are synchronized by normal Attribute Flows (SyncRule or MA) to Active Directory.

    If you give the users the appopriate rights via MPR to edit the userphoto Attribute it is very easy that users can control their own photos. maybe you want to create a workflow to approve this first, depends on the companay business rules.

    I add some documentation to the script and post it here if you want

    Regards
    Peter

    Wednesday, September 4, 2013 11:04 AM
  • Hi Peter,

    That would be helpful, many thanks.

    Gaston,

     I specifically asked about codeless sync rules as I want to avoid writing a DLL and there are limitations with the FIM portal sync rules (for example, they cannot sync multi valued attributes to AD), so can I do a FIM to AD photo sync without writing a custom DLL?

    Thx


    IT Support/Everything

    Wednesday, September 4, 2013 11:13 AM
  • I specifically asked about codeless sync rules as I want to avoid writing a DLL and there are limitations with the FIM portal sync rules (for example, they cannot sync multi valued attributes to AD), so can I do a FIM to AD photo sync without writing a custom DLL?

    The method I suggested is codeless. You don't need to write any line of code. 

    Wednesday, September 4, 2013 11:38 AM
  • So here is the Script,
    its not complete my own development, i searched a lot on the net and create it from some snippets of other poeple. So if someone recognize parts of the script, thank to them ;-)

    The script checks an additional attribute from HR to check if the user has accept to photo publishing (legel issues here in germany), and depending on that set or remove the photo in FIM portal.

    This script is not perfect but it works in our environment, so use without warranty:

    ### Configuration and Variables
    set-variable -name URI -value "http://localhost:5725/resourcemanagementservice" -option constant
    $photoPath = "\\server\share\photos\"
    $logFile= "D:\SetUserPhoto_log.txt"
    Get-Date > $logFile
    
    function Write-Output-Text([string]$msg) { 
    	Write-Output $msg
    	Write-Output $msg >> $logFile
    }
    
    
    ### Loading FIM Powershell Command-Lets 
    if(@(get-pssnapin | where-object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {add-pssnapin FIMAutomation}
    
    ### Get all person objects from portal via FIMService
    $allObjects = export-fimconfig -uri $URI -onlyBaseResources -customconfig ("/Person")
    
    foreach ($exportObject in $allObjects) {
    
    	$curPhoto = $exportObject.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "Photo"}
    	$displayName = $exportObject.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "displayname"}
    	$employeeID = $exportObject.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "EmployeeID"}
    	$showUserPhoto = $exportObject.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "showUserPhoto"}
    
    if ($employeeID.Value -ne $null)
    {
    	if ($showUserPhoto.value -eq $false) 
    		{
    		### Dont set employee photo if user has declined photo publishing
    		### Remove photo from employees you declined publishing
    		$outMsg="EmployeeID: " + $employeeID.value + " - User declined photo publishing"
    		write-output-text($outMsg)
    		
    		if ($curPhoto.value -ne $null)
    			{
    			### Create change object
    			### Setting no value on the attribute will remove it.
    			$importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange
    			$importChange.Operation = 1
    			$importChange.AttributeName = "Photo"
    			$importChange.FullyResolved = 1
    			$importChange.Locale = "Invariant"
    
    			### Create import object and add the change object to it.
    			$importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
    			$importObject.ObjectType = $exportObject.ResourceManagementObject.ObjectType
    			$importObject.TargetObjectIdentifier = $exportObject.ResourceManagementObject.ObjectIdentifier
    			$importObject.SourceObjectIdentifier = $exportObject.ResourceManagementObject.ObjectIdentifier
    			$importObject.State = 1 
    			$importObject.Changes = (,$importChange)
    			$outMsg="EmployeeID: " + $employeeID.value + " - Delete current Photo for User: " + $displayName.Value
    			write-output-text($outMsg)
    			$importObject | Import-FIMConfig -uri $URI -ErrorVariable Err -ErrorAction SilentlyContinue
    			}
    		}
    	else
    		{
    		### Set complete user photo path and check for existance
    		$photoName = $photoPath + $employeeID.Value + "_t.jpg"
    		$file=dir $photoName -ErrorAction SilentlyContinue
    		
    		if ($file.exists -eq $true)
    			{
    			### Import photo from file and do a Bas64 encoding
    			[byte[]]$bytePhoto = Get-Content $photoName -encoding byte
    			$newPhoto=[System.Convert]::ToBase64String($bytePhoto)
    			
    			# Check if portal photo and file are identitcal
    			if($newPhoto -eq $curPhoto.value)
    				{
    				$outMsg="EmployeeID: " + $employeeID.value + " - Photo is identical"
    				Write-Output-Text($outMsg)
    				}
    			else
     				{
    				### Create import change object
    				$importChange = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportChange
    				$importChange.Operation = 1
    				$importChange.AttributeName = "Photo"
    				$importChange.AttributeValue = $newPhoto
    				$importChange.FullyResolved = 1
    				$importChange.Locale = "Invariant"
    				
    				### create import object and add change object to it.
    				$importObject = New-Object Microsoft.ResourceManagement.Automation.ObjectModel.ImportObject
    				$importObject.ObjectType = $exportObject.ResourceManagementObject.ObjectType
    				$importObject.TargetObjectIdentifier = $exportObject.ResourceManagementObject.ObjectIdentifier
    				$importObject.SourceObjectIdentifier = $exportObject.ResourceManagementObject.ObjectIdentifier
    				$importObject.State = 1 
    				$importObject.Changes = (,$importChange)
    				$outMsg="EmployeeID: " + $employeeID.value + " - Set UserPhoto for User: " + $displayName.Value
    				Write-Output-Text($outMsg)
    				
    				### Export change to WebService (Portal)
    				$importObject | Import-FIMConfig -uri $URI -ErrorVariable Err -ErrorAction SilentlyContinue
    				}
    			}
    		else
    			{
    			$outMsg="EmployeeID: " + $employeeID.value + " - No Photo found"
    			Write-Output-Text($outMsg)
    			}
    		}
    }
    }
    

    Wednesday, September 4, 2013 12:47 PM