Reaching SharePoint files from the command line

You work in the terminal. Your scripts, your pipelines, the tools you trust all assume a file lives somewhere you can name with a path. Then the file you need is in SharePoint, and the terminal has no way in. The browser wants you to click through three folders and a download dialog. OneDrive sync wants to mirror gigabytes onto your disk and then argue about which copy is the real one. And the proper answer, a Graph script, means an app registration, an access token, and forty lines of pagination before you have pulled down a single file.

The reason it is awkward is that none of the protocols you would reach for are there. There is no FTP, SCP, rsync, find, or tree behind SharePoint. A document library is a Microsoft Graph drive, reached over HTTP with OAuth, and nothing about it speaks the file-transfer vocabulary your fingers already have.

So I built that vocabulary. xfiles is five small command-line tools, each named for the Unix utility it stands in for, each taking a SharePoint URL where that utility takes a path.

When you just need one file, xcp is scp. Two arguments, a source and a destination, and whichever one carries the SharePoint URL sets the direction:

$ xcp 'https://contoso.sharepoint.com/sites/Ops/Shared Documents/exports/vendors.csv' .

That pulls the file into the current directory. Use - as the local side instead of a filename and it streams, so a library file cats straight into whatever comes next without ever landing on disk:

$ xcp 'https://contoso.sharepoint.com/.../vendors.csv' - | xql 'select vendor, sum(spend) from - group by vendor'

No temp file, no download folder to clean up afterward. The data goes from the library into the next command and stops there.

When it is a whole tree, and you will do it again next week, xsync is rsync. It mirrors a directory to or from a library and moves only what changed, so the second run with nothing new transfers nothing:

$ xsync ./reports 'https://contoso.sharepoint.com/sites/Marketing/Shared Documents/Reports'
upload   Campaigns/launch-brief.docx
upload   Campaigns/metrics.csv
upload   Q2-forecast.xlsx

Done: 1 created, 4 copied, 0 deleted (0 up to date).

$ xsync ./reports 'https://contoso.sharepoint.com/sites/Marketing/Shared Documents/Reports'
Already in sync (4 up to date).

--dry-run prints the whole plan, every upload and delete, before it moves a byte. --delete makes the destination an exact mirror, removing what is no longer in the source, and asks first when it is talking to a terminal. It mirrors in either direction: push a local folder up, or pull a library down.

The other three are for finding your way around. xftp is an interactive session with the prompts you expect, ls and cd to move, get and put to transfer, for when you want to look before you leap. xfind walks the whole library and prints one matching path per line, filtered by name, type, or depth, plain enough to pipe into anything. xtree draws the folder structure as an indented tree with a count of what is inside. Between them you can explore a library you have never seen and take just what you want, without opening a browser once.

Under the surface all five are the same shape: a single Go binary, no daemon, no mounted drive, no configuration file to keep fed. They share one sign-in. The first time any of them connects it prints a short code and a URL, you approve it once in a browser, and the refresh token caches under ~/.config, so every run after that, across all five tools, is silent. One consent covers the suite, and the SQL tool xql rides the same session when you point it at a live list.

I built xfiles because SharePoint is where a great many organizations keep the files that matter, and the terminal is where a great deal of the work on those files actually happens. The gap between the two gets crossed by hand, one download at a time, or by a throwaway Graph script that each person writes again from scratch. A document library is a filesystem behind the wrong front door; xfiles is the right one.

The five tools install as one suite, open source under the MIT license, single static binaries for Linux, macOS, and Windows. The install lines and a walk through each tool are on the xfiles page. If you already know ftp, scp, rsync, find, and tree, there is almost nothing new to learn.

Getting data and documents in and out of a SharePoint estate cleanly and repeatably, without a person clicking through a portal to do it, is a recurring piece of the Microsoft 365 work I do for clients. When the files that run a process are trapped behind the browser and the automation around them is a drawer full of one-off scripts, that is the kind of work I like being brought in on.

Get in touch See xfiles →