0

When using Powershell to download a file from SharePoint Online, the file is not encoded or formatted properly.

With the below code, I am able to successfully authenticate to the site and download a file from SharePoint Online but the file appears to have a bunch of ancillary information from the site and not the actual data that it should have in the file after downloading it.

Also, using Postman I can connect to the SharePoint online site and download the file successfully and it is formatted correctly but when I perform this from PowerShell, using Invoke-RestMethod, it appears to not format the file correctly after saving the file to local disk.

Do I need to add a parameter or change the encoding to correctly format the saved file or am I missing something in the header? Any suggestions will be helpful.

Note: I would rather not use PowerShell PNP or CSOM as I want a solution that doesn't rely on any downloaded plug-ins, DLLs or any other local code requirements. I am trying to make it work with a REST call using OAuth token access.

[BEGIN CODE]

$filename = 'test1File.pdf'
$directory = 'C:\temp\'
$path = $directory + $filename
$outfile = "C:\temp\$filename"


Function GetAccessToken() {

$appId = '[app id]'                 #This is the Client ID
$appSecret = '[App Secret Here]'     #This is the Client Secret
$principal = '00000003-0000-0ff1-ce00-000000000000'             #This is the SharePoint Principal ID
$realm = '[Tenant ID Here]'                 #This is the Tenant Id
$targetHost = 'https://xxxxxx.sharepoint.com/sites/xxxx'  #This is the SharePoint Site
$resource = "00000003-0000-0ff1-ce00-000000000000/xxxxxx.sharepoint.com@[Tenant ID Here]"

$body = [ordered]@{
grant_type = 'client_credentials'
client_id = "$appId@$realm"
client_secret = $appSecret
resource = $resource
}

$accessTokenUrl = "https://accounts.accesscontrol.windows.net/$realm/tokens/OAuth/2"  
$global:Access_Token = Invoke-RestMethod -uri $accessTokenUrl -Body $body -Method Post

Write-Host "Token =" $global:Access_Token.Access_token

}

Function DownloadFile() {

$url = "https://xxxxxx.sharepoint.com/sites/xxxxxx/_api/web/GetFolderByServerRelativeUrl('/sites/xxxxxx/Documents')/Files('$filename')/$value"
$headers = @{'Authorization' = "Bearer $access_token";'Content-Type'="application/json";'Accept'="application/json;odata=verbose"}
$DownloadFile = Invoke-RestMethod -Uri $url -Headers $headers -Method Get -OutFile $outfile -Verbose
}

GetAccessToken

$access_token = $global:Access_Token.Access_token

DownloadFile

#Clear-Host
Write-Host "File Downloaded Successfully!"

[END CODE]

Below is a Snippet of what the file looks like after downloading it:

*/test1File.pdf')/Versions"}},"CheckInComment":"","CheckOutType":2,"ContentTag":"{ECB1B9A7-6774-467F-9A06-C91020BE52DD},2,1","CustomizedPageStatus":0,"ETag":"\"{[ETag]},2\"","Exists":true,"IrmEnabled":false,"Length":"215","Level":1,"LinkingUri":null,"LinkingUrl":"","MajorVersion":1,"MinorVersion":0,"Name":"test1File.pdf","ServerRelativeUrl":"/sites/xxxx/Documents/test1File.pdf","TimeCreated":"2021-07-02T19:29:25Z","TimeLastModified":"2021-07-02T19:29:25Z","Title":null,"UIVersion":512,"UIVersionLabel":"1.0","UniqueId":"[Unique ID]"}}

1 Answer 1

0

[SOLUTION] instead of using /$value at the end of the URL use /OpenBinaryStream().

example: https://mycompany.sharepoint.com/sites/MySite/_api/web/GetFileByServerRelativeUrl('/sites/MySite/Shared%20Documents/MyDocument.docx')/OpenBinaryStream().

Once I used /OpenBinaryStream() I was able to see the downloaded file correctly. The answer was found in the below article.

Download file contents from SharePoint Online via REST

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.