Matthew McDermott
Matthew McDermott

Reputation: 642

Update Contact Image from PowerShell through Microsoft Graph

I am writing a script to create new Contacts for a user in Exchange Online. Using the Microsoft Graph I can easily create Contacts using a POST to https://graph.microsoft.com/v1.0/me/contactFolders.... I can also request the photo from another contact using GET on https://graph.microsoft.com/v1.0/me/contactFolders/$($contactFolder)/contacts/$($contactId)/photo/$value and store the result then pass the photo value in the body of the PATCH back to that address and update the photo for other contacts.

What I cannot figure out how to do is read a file from disk (in my case a jpg file) and then properly encode it to send it in the body of the request above to update the contact.

I am using this doc: https://learn.microsoft.com/en-us/graph/api/profilephoto-update?view=graph-rest-1.0

I see that the type expected is "photo": { "@odata.type": "microsoft.graph.profilePhoto" }

The doc says:

In the request body, include the binary data of the photo in the request body.

I am struggling to figure out the image file read and encode for sending it as the -Body parameter to Invoke-RestMethod. Like I said, I can do this now if I send an existing photo as the body. I am just missing something in reading it from disk.

The following is what I tried and it does not work (contactPhotos is from my directory):

$photoBinary = [convert]::ToBase64String((get-content -Path $contactPhotos[0].FullName -encoding byte))

Upvotes: 0

Views: 1369

Answers (2)

Glen Scales
Glen Scales

Reputation: 22032

You shouldn't need to base64 Encode the image file (eg if you take a look at the results of your get request the result shouldn't be Base64 encoded). The following works for me okay

    $token = ($Context.AcquireTokenAsync("https://graph.microsoft.com", $ClientId , "urn:ietf:wg:oauth:2.0:oob", $PromptBehavior)).Result
    $Header = @{
        'Content-Type'  = 'application\json'
        'Authorization' = $token.CreateAuthorizationHeader()
    }
    $id = "AAMkADczNDE4Y......."
    $RequestURL = "https://graph.microsoft.com/v1.0/me/contacts('" + $id + "')/photo/`$value"
    $photoBinary = [System.IO.File]::ReadAllBytes("c:\temp\dd.jpg")
    $UserResult = (Invoke-RestMethod -Headers $Header -Uri $RequestURL -Method Put -Body $photoBinary -ContentType "image/jpeg").value

Upvotes: 3

Peter Ombwa
Peter Ombwa

Reputation: 231

You can try this instead. There is no need to base64 Encode the image.

$Headers = @{
    "Authorization" = $Token
    "Content-Type" = "image/jpeg"
}

$ProfilePic = ([Byte[]] $(Get-Content -Path "C:\path-to-pic" -Encoding Byte -ReadCount 0))

Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/me/contactFolders/{contact-folder-id}/contacts/{contact-id}/photo/$value" -Method Put -Headers $Headers -body $ProfilePic

Upvotes: 1

Related Questions