0 votes

Hello,

I am able to pull photo's of our employees from our HR solution into our active directory. However the HR api only provides a base64 encoded string.

This string then needs to be decoded and put into the right attributes for it to show on our active directory.

I tried a few powershell scripts I found, and while these work manually I am unable to get any of them to work together with Adaxes.

So, what we would like to have is the following:

We get the base64 encoding from our HR solution, we put this into: adm-CustomAttributeBinary1 from there a scheduled task should pick that up, decode it and put it into "ThumbnailPhoto" I believe.

I think that's the best way to get this to work, if you have any better solutions or see any problems. Please let me know.

by (40 points)

1 Answer

0 votes
by (270k points)

Hello,

There is no need to first save base64 into binary attributes of users and then set them as photos in a scheduled task. You can directly convert base64 into a byte array and set as photo. Here is an example of how that can be done. In the script:

  • $photoAttributeName - Specifies the LDAP name of the attribute that will be updated with the picture.
  • $photoBytesBase64 - Contains the base64 representation of the picture to set.
$photoAttributeName = "thumbnailPhoto" # TODO: modify me

$photoBytes = [System.Convert]::FromBase64String($photoBytesBase64)

function ResizePhoto ($photoBytes, $maxSize, $reduceSizeStep, $reduceSizeInPercents, $maxWidth, $maxHeight)
{
    if ($reduceSizeInPercents -ge 100)
    {
        return ,$photoBytes
    }

    try
    {
        # Calculate the new size, preserve ratio
        $original = [System.Drawing.Image]$photoBytes

        $width = $original.Width
        $height = $original.Height

        if ($NULL -ne $maxWidth)
        {
            if ($width -le $maxWidth -and $height -le $maxHeight)
            {
                return ,$photoBytes
            }

            $ratioX = $maxWidth / $width
            $ratioY = $maxHeight / $height
        }
        else
        {
            $ratioX = ($width - (($width / 100) * $reduceSizeInPercents)) / $width
            $ratioY = ($height - (($height / 100) * $reduceSizeInPercents)) / $height
        }

        $ratio = $ratioY
        if ($ratioX -le $ratioY)
        {
            $ratio = $ratioX
        }

        # Resize the picture
        [int]$newWidth = $width * $ratio
        [int]$newHeight = $height * $ratio

        $newPicture = New-Object System.Drawing.Bitmap($newWidth, $newHeight)
        $graph = [System.Drawing.Graphics]::FromImage($newPicture)

        $graph.Clear([System.Drawing.Color]::White)
        $graph.DrawImage($original, 0, 0, $newWidth, $newHeight)

        $memoryStream = New-Object System.IO.MemoryStream
        $newPicture.Save($memoryStream, [System.Drawing.Imaging.ImageFormat]::Jpeg)
        $newPictureBytes = $memoryStream.ToArray()
    }
    finally
    {
        # Release resources
        if ($original) { $original.Dispose() }
        if ($graph) { $graph.Dispose() }
        if ($newPicture) { $newPicture.Dispose() }
        if ($memoryStream) { $memoryStream.Dispose() }
    }

    if (($NULL -ne $maxSize) -and 
        ($newPictureBytes.Length -gt $maxSize))
    {
        $reduceSizeInPercents += $reduceSizeStep
        $newPictureBytes = ResizePhoto $photoBytes $maxSize $reduceSizeStep $reduceSizeInPercents
    }

    return ,$newPictureBytes
}

# Update thumbnailPhoto
$maxSize = 102400
if ($photoBytes.Length -gt $maxSize)
{
    $thumbnailPhotoBytes = ResizePhoto $photoBytes $maxSize 1 0 $NULL $NULL
}
else
{
    $thumbnailPhotoBytes = $photoBytes
}

# Update target user
$Context.TargetObject.Put($photoAttributeName, $thumbnailPhotoBytes)
$Context.TargetObject.SetInfo()

Also, you can have a look at the following script from our repository: https://www.adaxes.com/script-repository/update-user-photo-in-ad-and-microsoft-365-from-binary-attribute-s616.htm.

0

Hello,

Thank you so much. I am bit confused tho. How does this script know what the base64 of the image is?

I need to put the code from our HR api into a attribute somewhere right? Else it wont know what to decode?

Or am I misreading it?

0

Hello,

How does this script know what the base64 of the image is?

As you mentioned in your question you can request pictures in base64 format from your HR system. The result of the request should be set to the $photoBytesBase64 variable of the script.

I need to put the code from our HR api into a attribute somewhere right? Else it wont know what to decode?

No, saving code to an attribute will not work.

0

Hi,

Sadly I do not have the option to set the request from the API into that variable.

I can only push the result from the request into a predefined mapping (Azure Provisioning Agent style).

Thats why I am pushing it into the adm-CustomAttributeBinary1.

So there's no way to decode it from there. Sadly I am limited to what the HR api provides which is always a encoded string I am also limited by the interaction allowed via the Provisioning Agent.

So reading this correctly: You are saying this will not work.

0

Hello,

Sorry for the confusion, but we are not sure about the workflow you have. Do we understand correctly that you use some software dedicated for your HR system that output pictures of users in base64 format? If that is correct, do you make a single request per user and plan to manually enter the retrieved data into a custom binary attribute?

0

Yes,

We use the Azure provisioning agent to interface with our HR system.

This has predefined paths that it can gather from the API and you can then map these to attributes within AD.

So currently I am mapping the Photo attribute within our HRM to the adm-customattribute1 (ex) this works fine.

Every user thats in the testscope gets the customattribute1 filled with the base64 encoding string. I would love to put this directly into the thumbnailphoto but that wont work as it needs decoding first.

So my guess was; I have the dedicated software put it into that attribute on AD side for every user and then have Adaxes check all of those encoded strings, decode them and put them into the appriopate places in AD.

0

Hello,

Thank you for the provided details. In this case, it is not possible to use Adaxes custom attributes (e.g. adm-CustomAttributeBinary1) as they are not available in Active Directory. Do we understand correctly that you extended your AD schema with a binary attribute and that is where you save the pictures in base64 format? If that is correct, try using the script from our repository that we referenced earlier. Here is the link to it again: https://www.adaxes.com/script-repository/update-user-photo-in-ad-and-microsoft-365-from-binary-attribute-s616.htm. To perform the update only in AD, remove everything in the script after the below lines.

$Context.TargetObject.Put($photoAttribute, $thumbnailPhotoBytes)
$Context.TargetObject.SetInfo()
0

Hi,

I am trying your suggestions now but none work, this is I think caused by not decoding the base64 before trying to resize it.

So I will try to explain again:

We get a base64 encoded string from our HR side. We put this encoded string into a custom attribute that accepts the string.

Lets say for example this is the string that's given to us via the provisioning agent. RoyalTS_BsWiGLlXZW.png

This string cannot be loaded as it isnt decoded yet. Now what I can do manually in powershell is the following:

[System.Tex.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('stringfromscreenshothere')

this will give me a new string derived from the original string. If I then take that output and put it in for example "ThumbnailPhoto" I will have the picture in AD.

However I dont wanna do the powershell step manually for everyone, so thats what I am trying to achieve.. I hope its now more clear. :)

For more context if I use the following website: https://www.base64decode.org/

I can put in the string from our HR api into the first box; and then I can use the output (second box) and put that into 'thumbnailphoto' and I will have a image.

The error I am getting: RoyalTS_K3qPqsENYm.png

If I do the workflow manually it goes like this:

  1. Sync users; API puts the base64 encoded string into jpegPhoto (the only native AD attribute to accept it.)
  2. Then I take that string and put it into the decode website I mentioned.
  3. I put this string into the attribute photo.
  4. Then I can use the script (https://www.adaxes.com/script-repository/update-user-photo-in-ad-and-microsoft-365-from-binary-attribute-s616.htm) to make it suitable for "ThumbNailphoto" and in the end I have a working photo there.

In screenshot form: ydxGejmhmN.png

I hope that makes it more clear. :) I would really love it if we could solve this issue.

0

Hello,

Thank you for clarifying. If you save the base64 code into an attribute using Adaxes pipeline, you can use a business rule triggering After updating a user with the script that will use the decoding part you provided in the previous post. The rule will look like the following: image.png The below script should do the trick:

$binaryPropertyName = "jpegPhoto" # TODO: modify me

# Get picture to set
$encodedValue = $Context.TargetObject.Get($binaryPropertyName)
$valueToSet = [System.Tex.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($encodedValue)

# Update the user
$Context.TargetObject.Put("thumbnailPhoto", $valueToSet)
$Context.TargetObject.SetInfo()

Unfortunately, we are currently very limited in resources and have no possibility to fully test the workflow. Should you, still face issues with it, we encourage you to address the request to our consulting partners that provide professional services: https://www.adaxes.com/purchase_consultants.htm. Sorry for the inconvenience and thank you for your understanding.

Related questions

0 votes
1 answer

Hi. The new version that is "very soon" to be released(1-2 weeks). Is it going to be possible to set/change those from the web-interface. Would be very handy for example the HR ... .. 51252.aspx http://www.faq-o-matic.net/2011/02/07/b ... directory/ //Brandur

asked Jun 15, 2011 by Brandur (100 points)
0 votes
1 answer

Hi, we currenlty have a business rule to send an email everytime the Title, Manager, Department, accountExpires, EmployeeType or FirstName attributes are ... Unit: %BusinessUnit% End Date: %accountExpires% Effective Date of Change: %adm-CustomAttributeDate2%

asked Feb 14 by KevC (60 points)
0 votes
1 answer

Hello, We need to be able to put the ticket number into the custom command 'Deprovision'. Action -> Modify the user: set description to [ ... deprovision process set adminDescription with ticket number run Custom Command 'Deprovision' regards Helmut

asked Oct 14, 2020 by a423385 (510 points)
0 votes
1 answer

Hi I am trying to utilise the ADSI more and srver side scripting as an attempt to gain a wider knowledge and understanding of the Adaxes objects and interfaces. I have ... to the directory $user.SetInfo() } catch { $Context.LogException($_.Exception) } }

asked Aug 25, 2022 by will17 (350 points)
+1 vote
1 answer

I have been tasked with adding certain text to teh approval emails. What variable can i use for the object that the approval is required on? everything i currently select shows for the manager of the user?

asked Apr 9, 2020 by Derek.Axe (480 points)
3,326 questions
3,026 answers
7,727 comments
544,678 users