We use cookies to improve your experience.
By your continued use of this site you accept such use.
For more details please see our privacy policy and cookies policy.

Script repository

Update user photo in AD and Microsoft 365 from Binary attribute

November 06, 2023 Views: 1807

The script updates a user photo in AD and Microsoft 365 using the value stored in a Binary attribute of the user. To run the script, create a custom command, business rule or scheduled task configured for the User object type.

Parameters:

  • $copyFromPropertyName - Specifies the LDAP name of the Binary attribute storing the picture to be set.
  • $photoAttribute - Specifies the LDAP name of the attribute that will be updated with the picture stored in the attribute specified in the $copyFromPropertyName variable.
Edit Remove
PowerShell
$copyFromPropertyName = "adm-CustomAttributeBinary1" # TODO: modify me
$photoAttribute = "thumbnailPhoto" # TODO: modify me

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
}

# Get the picture
try
{
    $photoBytes = $Context.TargetObject.Get($copyFromPropertyName)
}
catch
{
    $Context.LogMessage("No picture specified in attribute $copyFromPropertyName.", "Warning")
    return # No picture
}

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

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

if ($NULL -eq $Context.TargetObject.AzureID)
{
    $Context.LogMessage("User %fullname% has no account in Microsoft 365.", "Warning")
    return
}

$userPhotoBytes = ResizePhoto $photoBytes $NULL $NULL $NULL 648 648

# Connect to Microsoft Graph PowerShell
$accessToken = $Context.CloudServices.GetAzureAuthAccessToken()
Connect-MgGraph -AccessToken ($accessToken | ConvertTo-SecureString -AsPlainText -Force)

try
{
    # Create temp file
    $tempFile = New-TemporaryFile
    [System.Io.File]::WriteAllBytes($tempFile.FullName, $userPhotoBytes)
    
    # Update the user's photo
    Set-MgUserPhotoContent -UserId $Context.TargetObject.AzureID -InFile $tempFile.FullName
}
finally
{
    # Remove the temp file
    Remove-Item $tempFile -Force
}
Comments 2
avatar
Ray Bilyk Jul 19, 2023
Is there a way for Adaxes to look if a user does NOT have a photo in O365, and upload the photo if they don't?
avatar
Support Jul 20, 2023
Hello Ray,

It should be possible using the Get-UserPhoto cmdlet in the script. However, starting from Adaxes 2023, you can manage Azure AD objects directly. Meaning that you can use much simpler approaches to achieve the same.
Leave a comment
Loading...

Got questions?

Support Questions & Answers