3

Programmatically downloading from Dropbox with PowerShell is trivial. With a link to a shared file https://www.dropbox.com/s/sdfjjthwrf32yFileName.pdf?dl=0, you just replace www.dropbox.com by dl.dropboxusercontent.com to give https://dl.dropboxusercontent.com/s/sdfjjthwrf32yFileName.pdf?dl=0 and can then use Invoke-WebRequest to fetch that file via a script (as long as the permissions on it are open for anyone to read).

With OneDrive, I have spent a few hours looking, and found no way to download a file with PowerShell. Some websites talk about OneDrive for Business, this question is not about OneDrive for Business as I do not know about or use that, this is specifically about OneDrive.

What I want to do is really simple, i.e. share a file in OneDrive, then get the share link, then be able to programmatically download that file using PowerShell (as the file is set to "anyone can view" so I should not really require authentication). Here is how I would share that file on the OneDrive.live.com site: enter image description here

I then change the file from "Anyone can Edit" to "Anyone can View", and this gives me a link that looks like this:

$url = "https://1drv.ms/u/s!Bjfhd-pwUc_asdcadfasdfTYFASDFASDf?e=aksdHDG"

I then try to download it using Invoke-WebRequest:

Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile "C:\MyFile.txt"

But all I get is a small stub of javascript output (note that the above is not a real link, but an example)

With Dropbox, it is trivially simple, so how can we do this with OneDrive?

The closest I have come might be the OneDrive module, but I don't know how to generate an OAuth2 token that I can pass to the script (and it completely breaks the purpose of this exercise, as if I have to provide credentials to download an "Anyone can View" file, then I cannot create a script that others can use to download a file without them also providing credentials; we should not need to provide credentials if the file in question is set as "anyone can view". That is the case for the Dropbox example; if the file is to read-only for everyone, then no credentials are required, as that would obviously be sort of ludicrous - it would be like demanding a key to get through an unlocked and open doorway that has a sign above it saying "Anyone may freely enter here without a key").

Install-Module -Name OneDrive -Force

Please note: To stress, this question is not about OneDrive for Business, that is something that I do not know or use.

YorSubs
  • 3,194
  • 7
  • 37
  • 60

1 Answers1

1

You can download the shared file directly by using the OneDrive API. To do so, you have to convert your sharing URL into a sharing token and pass it to the OneDrive API. This example shows the needed C# code. You can derive the following PowerShell function from it:

function Get-OneDriveDirectDownloadUrl {

    param(
        [string]
        $SharingUrl
    )

    $base64Value = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($SharingUrl))
    $encodedUrl = 'u!' + $base64Value.TrimEnd('=').Replace('/','_').Replace('+','-')
    return 'https://api.onedrive.com/v1.0/shares/' + $encodedUrl + '/root/content'
}

With that function, you can convert your sharing URL like this:

Get-OneDriveDirectDownloadUrl -SharingUrl 'https://1drv.ms/u/s!Bjfhd-pwUc_asdcadfasdfTYFASDFASDf?e=aksdHDG'

And you will receive the following direct download URL:

https://api.onedrive.com/v1.0/shares/u!aHR0cHM6Ly8xZHJ2Lm1zL3UvcyFCamZoZC1wd1VjX2FzZGNhZGZhc2RmVFlGQVNERkFTRGY_ZT1ha3NkSERH/root/content
stackprotector
  • 10,498
  • 4
  • 35
  • 64
  • I tested this with some files and it works flawlessly, thanks. I also tried sharing a folder with your solution, but that generates an error `Invoke-WebRequest : {"error":{"code":"itemNotFound", "The specified item does not have content."`. Your post completely answers my question, so I am very grateful for that, but for completeness, do you know how we might download an entire folder, given a sharing URL to that folder? – YorSubs Dec 21 '22 at 07:47
  • As far as I know, the only way to download folders - in general, not only on OneDrive - is to zip them before downloading. So that in the end, you download a single file again. – stackprotector Dec 21 '22 at 08:35