Script repository

Update user photo in AD and Microsoft 365 from Binary attribute

Updated on: Jan 18, 2026, Views: 3004

User accounts, Microsoft 365

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

Parameters

  • $copyFromPropertyName - the name of the Binary attribute storing the picture to set.
  • $photoAttribute - the name of the attribute that will be updated with the picture stored in the Binary attribute.
$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

You must be signed in to comment.

  • Ray Bilyk

    Ray Bilyk

    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?

    • Support

      Support

      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.

Got questions?

Support Questions & Answers

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.