Choose SPSync when a nightly export script has become something people depend on; choose PnP PowerShell for one-off exports, migrations and tenant-specific logic you are happy to own.
Documentation reviewed
Where PnP PowerShell fits
- Free and open source
- extremely flexible, since you write exactly what you need
- huge community and cmdlet coverage (700+ cmdlets)
- cross-platform: Windows, macOS and Linux
Where it breaks
- You own paging, throttling and backoff, delta detection, delete tracking, schema drift and retries yourself
- no built-in normalisation of lookups or multi-value columns into relational tables
- support comes from the open-source community; the PnP PowerShell documentation states there is no SLA or direct Microsoft support for the module
- the script becomes tribal knowledge that leaves when its author does
- you register and manage your own Entra ID app registration and its credentials
Feature by feature
| Feature | SPSync | PnP PowerShell and custom scripts |
|---|---|---|
| SharePoint Online support | Core product | Yes, via 700+ cmdlets for Microsoft 365 |
| On-prem SharePoint support | On the roadmap | Yes, PnP PowerShell also targets on-prem SharePoint |
| Destinations | Relational, warehouse, lake and search/vector destinations: 20 destination engines (30+ named targets such as Azure SQL, MariaDB and Supabase), including SQL Server, Postgres, BigQuery, Databricks, ClickHouse, Parquet, Iceberg, pgvector and Azure AI Search; see /destinations/ | Whatever you write the script to target |
| Lookup normalisation | Lookups become joinable key columns automatically | You build this yourself |
| Multi-value columns | Child tables | You build this yourself |
| Deletes | Soft delete by default, hard delete with the command-line tool | You build delete detection yourself |
| Delta sync | Every few minutes by default, plus a reconcile, weekly by default | You build delta queries and a scheduler yourself |
| Schema evolution | New columns appear automatically; on SQL Server, PostgreSQL, MySQL, ClickHouse, Oracle, SQLite and DuckDB retyped columns get a _v2 column | You handle schema drift in your script |
| Hosted option | SPSync in your Azure | None; you host wherever the script runs |
| Desktop app | macOS and Windows | Not applicable; it is a PowerShell module |
| CLI / CI | Built-in CLI | It is a script; CI is whatever you wire up |
| Per-site least-privilege permissions | Delegated sign-in or app-only with Sites.Selected, bring-your-own-app | You register your own Entra ID app and scope its permissions |
| Pricing model | Licensed per installation and per target family, on annual terms, with Standard Support included; no public price list, quoted after a call | Free; your cost is engineering time |
A finance analyst needed last month’s purchase orders out of a SharePoint list, so someone in IT wrote a PnP PowerShell script that exported them into a SQL table. It ran once, then it ran every night, and now the month-end report reads that table. The person who wrote the script has moved to another team, and the script has not been opened since.
Where a script is the right tool
PnP PowerShell is the right tool for a one-off export, a migration that runs once, or logic so specific to your tenant that no packaged product would cover it. Our PnP PowerShell to SQL Server script is a working starting point, with the sign-in setup PnP needs today. It is free, it runs on Windows, macOS and Linux, its cmdlets cover SharePoint and much of Microsoft 365, and an active community keeps it current. If you need an answer today and you are happy to own it, a script is often the fastest way there.
The script that became infrastructure
The trouble starts when the script keeps running. Reading a list once is easy. Keeping a database in step with that list, correctly, every night, for years, means the script now owns:
- paging through large lists, and respecting Graph throttling and
Retry-After - telling a changed item from an unchanged one, and noticing deletes
- a column that is renamed or retyped in SharePoint
- recovering from a run that failed at 3am, and someone finding out that it did
- the app registration and its credentials
None of that is exotic. All of it needs building, testing and maintaining, and it tends to live in one person’s head. If your script is Python rather than PowerShell, a SharePoint list into Postgres or SQL Server with Python shows the delta paging, Retry-After and delete handling in full, and what is left over.
What SPSync takes off your hands
Paging, throttling, delta sync, delete tracking and schema evolution are built in. Lookups arrive as key columns you can join on and multi-value columns as child tables, with no flattened strings for a downstream step to parse. The point to switch is usually when an export has turned into a scheduled job that people depend on.
Retiring the script
- Read what the script does today: which lists and columns, and how it detects changes and deletes.
- Sign in to SharePoint in SPSync and choose the lists the script exports.
- Choose a destination database. The initial full load and the delta syncs after it replace the script’s read logic.
- Compare the tables with the script’s output. Any custom transformation the script did moves into a view on the destination.
- Remove the scheduled task or CI job that ran the script.
If you liked scripting it
The command-line tool is the closest match to what you had: one YAML config, run from cron, CI or a server, reviewed like any other code. Teams that prefer a UI use the desktop app on macOS and Windows. If your nightly export is an SSIS package rather than a script, SPSync vs SSIS covers the same ground for Integration Services. SPSync in your Azure, a managed application for your own subscription, is deployed with you on a call while the Marketplace listing is prepared. Once deployed there is nothing to install.
SPSync as a PnP PowerShell alternative for SharePoint lists
SPSync takes over the parts a long-lived script had to own: paging, throttling, change detection, deletes and column changes. Its command-line tool keeps the habits of the script, one YAML file run from cron or CI, and any custom logic moves into views on the destination.
Other alternatives
- Power Automate: low-code flows that react to item changes, quicker to build than a script and slower for whole lists.
- Azure Data Factory: a managed copy step with monitoring, for teams who would sooner run pipelines than scheduled scripts.
- ZappySys: SSIS and ODBC access to SharePoint Online, a middle ground between hand-written code and a packaged sync.
- KingswaySoft: drag-and-drop SSIS components for SharePoint lists and libraries, for teams that already maintain SSIS packages.
Frequently asked questions
Is PnP PowerShell supported by Microsoft?
The PnP PowerShell site states that the module has no SLA and no direct Microsoft support, and help comes from the open-source community (checked 2026-10-16). Every SPSync licence includes Standard Support.
Can I still script SPSync?
Yes. The spsync command-line tool runs from cron, a CI job or a server and reads one YAML config, which you can review in a pull request like any other code.
Where do the custom transformations from my script go?
Move them into views on the destination database. SPSync writes each list as SharePoint holds it, so a view that renames, filters or combines columns keeps the logic visible to anyone who reads SQL.
Desktop, Azure or command line
All three editions run the same engine, write the same tables and use the same licence key, so the choice comes down to who looks after the sync.
Desktop app
For macOS and Windows. Sign in with Microsoft, tick the lists, choose a database and sync from your own machine on the schedule you set. Delegated sign-in needs no admin unless your tenant requires admin consent for apps.
In your Azure
SPSync in your Azure, a managed application for your own subscription, is deployed with you on a call while the Marketplace listing is prepared. Once deployed it is always on, so the sync keeps running with every laptop closed.
Command line
Every replication is a YAML file you can review and commit. Run it from a server, a container or a CI pipeline, and re-run it safely any time.