Home > Enterprise >  Microsoft Graph API - Powershell - Retrieve Excel file attachment
Microsoft Graph API - Powershell - Retrieve Excel file attachment

Time:12-01

I'm use Microsoft Graph API for retrieve attachments in mails.

I use this endpoint for retrieve attachments https://graph.microsoft.com/v1.0/users/{mailbox.mail}/messages/{message.id}/attachments/

$callAPI = @{
  Headers = @{
      Authorization = "Bearer $token"
  }
  Uri = "https://graph.microsoft.com/v1.0/users/{mailbox.mail}/messages/{message.id}/attachments/"
  Method = "GET"
}

$attachments = (Invoke-RestMethod @callAPI).value;

After I use foreach for retrieve attachment content with this endpoint : https://graph.microsoft.com/v1.0/users/{mailbox.mail}/messages/{message.id}/attachments/{attachment.id}/$value

$callAPI = @{
   Headers = @{
     Authorization = "Bearer $token"
   }
   Uri = "https://graph.microsoft.com/v1.0/users/{mailbox.mail}/messages/{message.id}/attachments/{attachment.id}/$value"
   Method = "GET"
}

$content = Invoke-RestMethod @callAPI;

And I use this command line for save file :

Set-Content -Path "$($attachmentsTempDestination)\$($attachment.name)" -Value $content

But my file is bad and not recognized by Excel.

I try the endpoint for attachment content in PostMan and I save response ( Picture : PostMan save response). The saved file is correct.

Probably, it's my last PowerShell command for save content isn't good, but I don't know how do for fix this issue.

Please help me !


With @glen-scales answer, I find a good PowerShell code for my usecase :

  $callAPI = @{
      Headers = @{
          Authorization = "Bearer $token"
      }
      Uri = "https://graph.microsoft.com/v1.0/users/{mailbox.mail}/messages/{message.id}/attachments/"
      Method = "GET"
    }

$attachments = (Invoke-RestMethod @callAPI).value;

foreach ($attachment in $attachments) {     

[System.IO.File]::WriteAllBytes("$($attachmentsTempDestination)\$($attachment.name)",[System.Convert]::FromBase64String($attachment.contentBytes)) 
    
}

CodePudding user response:

The attachment content is a base64 encoded string so the way your using set-content will just be writing that base64 content to the file which would not be valid.

You need to first convert it to a byte array and then you should be able to do something like

Set-Content -Path "$($attachmentsTempDestination)\$($attachment.name)" -Value [System.Convert]::FromBase64String($content) -Encoding Byte

otherwise you could also use (which maybe faster as set-content)

[System.IO.File]::WriteAllBytes("$($attachmentsTempDestination)\$($attachment.name)",[System.Convert]::FromBase64String($content))
  • Related