Script Repository


Upload user photo to Office 365

December 07, 2017
3287

The scripts upload a user's photo to Office 365. The photo will appear in client applications, such as Microsoft Outlook Web App, Lync, Skype for Business, and SharePoint.

The 1st script uploads the photo stored in AD in the Picture (thumbnailPhoto) attribute, and the 2nd one uploads a photo from a file. When uploading from a file, the image will be optimized for the best viewing quality in Office 365 (648x648 pixels, best JPEG compression quality).

To upload pictures to Office 365, you can create a Scheduled Task that updates user photos on a regular basis. If you are uploading the AD photo, you can also create a Business Rule that runs the 1st script after updating the Picture attribute.

Sample Business Rule


1. Upload Image Stored in AD Attribute Picture (thumbnailPhoto)

Edit Remove
PowerShell
# Get user ID in Office 365
try
{
    $objectId = [Guid]$Context.TargetObject.Get("adm-O365ObjectId")
}
catch
{
    return
}

# Get the photo
try
{
    $pictureBytes = $Context.TargetObject.Get("thumbnailPhoto")
}
catch
{
    $Context.LogMessage("The user doesn't have a photo", "Warning")
    return
}

try
{
    # Connect to Exchange Online
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/?proxymethod=rps" `
    -Credential $Context.GetOffice365Credential() -Authentication Basic -AllowRedirection -WarningAction SilentlyContinue

    Import-PSSession $session -AllowClobber -DisableNameChecking
    
    # Update the user's photo
    Set-UserPhoto $objectId.ToString() -PictureData $pictureBytes -Confirm:$False
}
finally
{
    # Release resources
    Remove-PSSession $session
}

2. Upload Image from File

Parameter:

  • $picturePath - specifies a path to the picture file. You can use value references in it (e.g. %username%). When the script is executed, they will be replaced with property values of the target user. For example, if you specify the following path: \\SERVER\share\%username%.jpg, and the script is executed on a user with username jdoe, the file path will be \\SERVER\share\jdoe.jpg.
Edit Remove
PowerShell
$picturePath = "\\SERVER\share\%username%.jpg" # TODO: modify me

function ResizePhotoForOffice365 ($picturePath)
{
    try
    {
        # Calculate the new size, preserve ratio
        $original = [System.Drawing.Image]::FromFile($picturePath)
        $ratioX = 648 / $original.Width
        $ratioY = 648 / $original.Height
        $ratio = $ratioY
        if ($ratioX -le $ratioY)
        {
            $ratio = $ratioX
        }
        
        # Resize the picture
        [int]$newWidth = $original.Width * $ratio
        [int]$newHeight = $original.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)
        
        # Set encoder settings for image quality
        $encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1)
        $encoder = [System.Drawing.Imaging.Encoder]::Quality
        $encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($encoder, 100)
        
        # Save file
        $tmpFilePath = [System.IO.Path]::GetTempFileName()
        $imageCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | where {$_.MimeType -eq 'image/jpeg'}
        $newPicture.Save($tmpFilePath, $imageCodecInfo, $($encoderParams))

        [Byte[]]$pictureBytes = Get-Content -Path $tmpFilePath -Encoding Byte
        [System.IO.File]::Delete($tmpFilePath)
        
        return ,$pictureBytes
    }
    finally
    {
        # Release resources
        if ($original) { $original.Dispose() }
        if ($graph) { $graph.Dispose() }
        if ($newPicture) { $newPicture.Dispose() }
    }
}

# Get user ID in Office 365
try
{
    $objectId = [Guid]$Context.TargetObject.Get("adm-O365ObjectId")
}
catch
{
    return
}

# Get the photo
if (-not(Test-Path -Path $picturePath))
{
    $Context.LogMessage("File '$picturePath' does not exist.", "Warning")
    return
}
$pictureBytes = ResizePhotoForOffice365 $picturePath

try
{
    # Connect to Exchange Online
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/?proxymethod=rps" `
    -Credential $Context.GetOffice365Credential() -Authentication Basic -AllowRedirection -WarningAction SilentlyContinue

    Import-PSSession $session -AllowClobber -DisableNameChecking -CommandName Set-UserPhoto
    
    # Update the user's photo
    Set-UserPhoto $objectId.ToString() -PictureData $pictureBytes -Confirm:$False
}
finally
{
    # Release resources
    Remove-PSSession $session
}

Comments ( 0 )
No results found.
Leave a comment