Sanitized portfolio version of a .NET 8 migration tool for moving classic SharePoint 2016 content into modern SharePoint Online pages.
- SharePoint administrators planning a move from SharePoint 2016 to SharePoint Online
- Microsoft 365 and SharePoint consultants who need a migration starting point
- internal platform teams validating how much classic content can be transformed automatically
This project is aimed at the messy middle of SharePoint migration work: not just exporting files, but recovering useful page structure and content from legacy sites and rebuilding it into something reviewable in SharePoint Online.
It is most useful when a team wants to:
- analyze classic pages before a full migration
- preserve more than just raw page text
- create modern destination pages in a sandbox for review
- keep a visible paper trail through logs and analysis artifacts
This project is more than a simple export/import script. It sits between two different SharePoint worlds:
- a legacy on-prem SharePoint 2016 source environment
- a modern SharePoint Online destination environment
The tool discovers source pages, reads content from multiple legacy representations, resolves page-template mappings, rewrites internal links, and creates modern destination pages while keeping the source environment read-only.
The difficult part is that classic SharePoint content is not stored in one clean place. Depending on the page, useful information can live in:
- publishing or wiki page body HTML
- list item fields and metadata
- classic web part definitions
- rendered page HTML
- people fields that may need additional lookup calls
That means the migration pipeline has to combine API reads, HTML parsing, metadata normalization, and destination-side page assembly instead of relying on a single straightforward transformation.
flowchart LR
A["SharePoint 2016 Source Site"] --> B["SourcePageEnumerator"]
B --> C["SourceWebPartReader"]
C --> D["Page body + Quick links + Metadata + Web parts"]
D --> E["PageMappingResolver"]
E --> F["PageMigrationService"]
F --> G["SharePoint Online Modern Pages"]
D --> H["Analysis Output and Run Logs"]
- Connects to one or more legacy SharePoint 2016 source sites.
- Enumerates available pages and skips source default pages by design.
- Reads source metadata, page body content, quick links, and classic web parts.
- Resolves source layouts/content types into modern destination templates.
- Rewrites internal source links to destination-friendly modern URLs.
- Optionally cleans the destination
Site Pageslibrary. - Creates modern pages and writes analysis artifacts for review and troubleshooting.
- The source environment is treated as read-only.
- Destination cleanup is optional and controlled by configuration.
- Existing destination name collisions are handled instead of silently overwriting pages.
- The tool writes analysis output and run logs so results can be reviewed before broader rollout.
- Bridging different authentication models for on-prem SharePoint and SharePoint Online.
- Extracting useful content from inconsistent legacy page structures.
- Mapping old layouts and content types onto newer page templates.
- Preserving reviewer visibility with source links, page inventories, and analysis files.
- Making reruns safer by avoiding accidental source writes and handling destination name collisions.
Main components in the repo:
src/PageMigrator/Program.csorchestrates the end-to-end run and prints an operator-friendly summary.src/PageMigrator/Auth/contains the source and destination authentication helpers.src/PageMigrator/Configuration/loads settings and interactive run inputs.src/PageMigrator/Services/SourcePageEnumerator.cslists source pages in a read-only way.src/PageMigrator/Services/SourceWebPartReader.csextracts page body content, quick links, metadata, leaders, and classic web parts.src/PageMigrator/Services/PageMappingResolver.csconverts legacy page layouts/content types into destination mappings.src/PageMigrator/Services/PageMigrationService.csbuilds modern pages, rewrites links, creates quick links, and applies migrated content.src/PageMigrator/Services/AnalysisWriter.csand related services write run logs and analysis files for validation.src/PageMigrator.Tests/contains focused unit tests for parsing and link-rewrite logic.
.NET 8PnP.Frameworkand SharePoint CSOM for SharePoint Online operationsHttpClientagainst SharePoint 2016 REST endpointsHtmlAgilityPackfor HTML cleanup and parsingxUnitfor unit tests
Current strengths of the project:
- reading legacy SharePoint 2016 pages from one or more source sites
- extracting publishing or wiki page body content
- reading list item metadata and quick links
- extracting supported classic web part content and inventories
- mapping source layouts and content types to destination page templates
- creating reviewable modern SharePoint Online pages in a destination site
This is not a full SharePoint migration platform. It is best understood as a targeted page-migration tool with analysis support.
Known limitations include:
- success depends on the structure and consistency of the source pages
- not every classic web part can be recreated as a true modern equivalent
- destination mappings are configuration-driven and may need extension for new page types
- it currently assumes a cautious operator workflow rather than unattended large-scale batch execution
- local build and test validation require a machine with the
.NET 8SDK/runtime available
- tenant URLs, user names, machine names, and secrets have been replaced with placeholders
- committed configuration files contain sample values only
- local overrides belong in
src/PageMigrator/appsettings.Development.json, which is ignored - generated output such as
bin/,obj/,Analysis/, andLogs/is ignored - organization-specific names and environment details were removed for this portfolio version
src/PageMigrator- console application and migration logicsrc/PageMigrator.Tests- unit tests for URL rewriting, web-part parsing, and content formattingdocs/EXAMPLE-MIGRATION.md- fake end-to-end walkthrough for a first trialdocs/PILOT-CHECKLIST.md- low-risk process for trying the tool with a sandbox sitedocs/RELEASING.md- maintainer notes for creating downloadable GitHub releasesdocs/LINKEDIN-LAUNCH-POST.md- ready-to-use launch copy for sharing the project
For a more operator-focused runbook, see src/PageMigrator/README.md.
cd src/PageMigrator
dotnet build
dotnet runUse a non-production destination site when testing cleanup or migration behavior.
If you want someone else to try the app with low risk, the best sequence is:
- point the tool at one small source site
- target a disposable SharePoint Online sandbox site
- keep
DeleteExistingPagesBeforeMigrationset tofalse - run the migration and inspect the destination pages plus
Analysis/output - review what mapped cleanly and what would need customization
The detailed pilot workflow lives in docs/PILOT-CHECKLIST.md.
For a public-safe fake example of how a trial run can look, see docs/EXAMPLE-MIGRATION.md.
This repo is now set up for downloadable GitHub releases.
- tag a version like
v0.1.0 - push the tag to GitHub
- GitHub Actions will build release zip packages for supported platforms and attach them to the release
The maintainer steps live in docs/RELEASING.md.
From the repo root:
dotnet restore src/PageMigrator.Tests
dotnet test src/PageMigrator.Tests --no-restoreThe tests cover targeted migration logic such as URL rewriting, web-part classification, and source HTML handling.
If you want to distribute the app to testers who should not build from source, the repo now includes release automation plus a short rollout checklist in docs/PILOT-CHECKLIST.md, a maintainer release guide in docs/RELEASING.md, and a launch post draft in docs/LINKEDIN-LAUNCH-POST.md.
This project is licensed under the MIT License.