Project Online Custom Fields Migration: What Transfers
Project Online custom fields migration, field by field: which objects transfer as-is, which need mapping, and which you rebuild, with the export feed for each.
Custom fields are where Microsoft Project Online migrations get genuinely hard. The .mpp export covers the headline data, tasks, dates, dependencies, but the metadata that makes your PMO's reports actually useful lives in enterprise custom fields, lookup tables, and calculated fields. Get those wrong and your dashboards arrive at the new platform looking right but reading wrong.
The path below runs the full custom-field migration: what Project Online stores where, how to inventory and audit before you move, the field-by-field mapping to a modern destination, and the four traps that account for ~80% of the post-migration "where did the data go?" tickets. It then widens to every other object a tenant holds (baselines, dependencies, cost fields, deliverables, issues and risks, administrative time, templates, permissions, portfolios, page layouts and views) so you can see, field by field, what transfers.
If you haven't read the headline migration walk-through yet, start with How to Migrate from Microsoft Project Online, it gives you the 6-week project frame this work fits into. For the budget side, the cost of migrating from MS Project Online in 2026 covers the labor that custom fields specifically drive, they're the single biggest variable in the data-migration line item.
Context: this post is one piece of the Microsoft Project retirement timeline, the consolidated reference covering all three Microsoft Project ecosystem retirements of 2026.
What transfers, in one paragraph. Tasks, outline, milestones, constraints, all four dependency types with lag, fixed costs and task-level custom-field values travel in the .mpp or MSPDI export and import as-is. Costs come across, and a .mpp or Project XML file imported into a new project brings its baseline as a baseline in Onplana. Working and resource calendars do not come across: the project uses the organization's working calendar. Lookup tables, field definitions, rate tables, cost-type fields, administrative time and Project Detail Page values exist only in the OData ProjectData feeds and transfer with mapping. Calculated-field formulas, deliverables, issues and risks, template bindings and workflows, page layouts, views, security categories and portfolio configuration do not transfer at all; you rebuild them from an inventory you documented before the export.
To see which task-level custom fields an export actually carries before you import it, open the file in Onplana Schedule and check View, Columns and fields.
TL;DR: 5-step custom-field migration plan
- Inventory every field via OData (Projects, Tasks, Resources) + every lookup table (week 1)
- Audit usage, retire anything below 5% coverage on the source side, not after migration (week 1–2)
- Snapshot calculated fields into static text/number fields BEFORE export, formulas don't migrate, values do (week 2)
- Map Project / Task / Resource fields to destination types and attachment points (week 3)
- Validate field values on the pilot project against the source OData read (week 4)
The same loop runs for every other row of the master table below: inventory the object in its own feed, audit what is still used, snapshot anything computed, map it to its destination, validate it on the pilot.
What transfers, field by field: the master mapping table
The master table is the whole Project Online migration on one screen: every object a tenant holds, where it sits once exported, where it lands in Onplana, whether it transfers as-is, with mapping, or not at all, and the trap to check before you sign off that row. Rows run in the order of the sections below.
| Project Online object | Where it lives in an export | Onplana destination | Transfers | Trap to check |
|---|---|---|---|---|
| Task-level custom field values | .mpp ExtendedAttribute data; OData Tasks?$expand=CustomFields |
Task custom field (Pro and above) | With mapping | File and reporting-database copies differ; OData wins |
| Project-level custom field values (PDP forms) | OData Projects?$expand=CustomFields; often absent from the .mpp |
Project custom field (Pro and above) | With mapping | PDP-entered values never reach the file |
| Resource-level custom fields (Skill Set, Cost Center) | OData Resources |
User profile field | With mapping | Imported as task fields by mistake |
| Field definitions (type, entity, required, formula) | OData CustomFields |
CustomFieldDefinition (PROJECT or TASK) | With mapping | Cost loses currency; Duration needs a unit |
| Flat lookup tables | OData LookupTables and LookupEntries; in no .mpp |
Dropdown or multi-select options, created before import | With mapping | Missing option imports as blank, silently |
| Hierarchical lookup tables | LookupEntries with MaskValue and ParentLookupEntryUID |
Tag tree, or a flattened dropdown | With mapping | Flattening drops the parent reports group by |
| Multi-value lookup values | ;#-delimited strings in the value feeds |
Multi-select field | With mapping | Collapses to one option unless split on ;# |
| Calculated fields | Formula in CustomFields; last value in the task and project feeds |
Static snapshot field, locked read-only | Value yes, formula no | Users edit the snapshot |
| Enterprise Global and project calendars | Base rules in the .mpp; exception days only partly |
The organization's working calendar, set up in Onplana | Does not transfer; set up by hand | Project-specific rules are not imported; dates shift |
| Resource-specific calendar exceptions | Enterprise Resource Pool only; not in the .mpp |
Per-person capacity in the capacity planner (Pro and above) | Does not transfer; re-enter | Sudden overallocation in one week |
| Tasks, outline, milestones, notes, constraints | .mpp or MSPDI XML |
Tasks with hierarchy, milestones, all eight constraint types | As-is | Template scaffolding imported as work |
| Finish-to-Start dependencies | MSPDI PredecessorLink |
Dependency (every plan, including Free) | As-is | Total count must match the source |
| SS, FF and SF dependencies with lag or lead | PredecessorLink type and LinkLag |
The same four types with lag, in days (every plan) | As-is, verify | Percent or hour lag has to become a day count |
| Cross-project dependencies | Only in the enterprise link; orphaned in a per-project file | Rebuilt link or documented commitment | Does not transfer | Successor reschedules to ASAP |
| Active baseline (Baseline 0) | .mpp when set in the desktop; OData ProjectBaselines when set by Publish |
Comes across as a baseline when the file is imported into a new project, with baseline cost per task (every plan) | Transfers into a new project; an append keeps the dates on each task only | Check the Baseline tab before anyone edits the imported plan |
| Baselines 1 through 10 | Same feed, numbered fields | OData CSV as the record of each set | Archive only | Nothing in the file restores them |
| Fixed Cost on tasks | .mpp Fixed Cost field |
Task cost | As-is | Zero-cost lines are flagged on import |
| Rate Table A with date tiers | OData Resources?$expand=CostRateTables; not in the .mpp |
Per-user rate card with effective date ranges | With mapping | Assignments before rates cost zero |
| Rate Tables B through E | Same feed | Billable rate or markup on the rate card, or documentation | Not as tables | Reports built on tables B to E |
| Baseline Cost and Actual Cost | With the baseline; ActualCost derived from TimesheetLines |
Baseline cost per task on import; static actuals or re-logged time entries (Pro and above) | Baseline cost as-is; actuals with mapping | Static actuals lose the audit trail |
| Cost-type custom fields (budget, contingency) | CustomFields of type Cost |
Project budget, or a cost custom field | With mapping | Implicit currency becomes a bare number |
| Deliverables | SharePoint Deliverables list per project site | Milestone in a portfolio (Business and above), or a documented commitment | Does not transfer | Omitted from every export, no warning |
| Issues list | SharePoint Issues list per project site | Issue log (type, severity, owner, target date) | With mapping, via CSV | Resolution history sits in a discussion field |
| Risks list | SharePoint Risks list per project site | Risk register | With mapping, via CSV | RelatedItems points at a SharePoint ID |
| Administrative time categories and entries | OData AdminProject; TimeSheetLines where TimeSheetLineClass eq 2 |
Tasks in a permanent administrative project (time tracking, Pro and above); entries archived as CSV | With mapping; entries archive | In no project file; pulls throttle |
| Enterprise Project Template base plan | One .mpp per template |
Imported project saved as a template (Professional and above) | As-is | Placeholder tasks |
| EPT field bindings, PDP layout, workflow | PWA admin configuration; SharePoint Workflow Foundation retired April 2, 2026 | Project form fields plus governance pipeline gates | Does not transfer; rebuild | Workflow stopped before the tenant did |
| Security categories, groups, templates | PWA Settings, Security; screen lists only | Organization roles plus project roles; custom roles (Business and above) | With mapping | "Team Member" holds both editors and status reporters |
| Portfolio hierarchy, business drivers, weights | Admin configuration; no export format | Portfolios (Business and above); evaluation criteria per governance gate | Does not transfer; rebuild | Hierarchy mirrors an old org chart |
| Strategic scores and scenario models | Scores via OData ProjectData; scenarios as PDF only | CSV and PDF archive | Export only | Old scenarios reused for new decisions |
| Page customizations and web parts | SharePoint page metadata; PnP export documents only | Dashboards and pages (Pro and above) | Does not transfer; rebuild | "Rebuild it later" becomes never |
| Views, tables, filters, groupings | PWA site configuration under Look and Feel | Saved views on the Projects page; list and board filters | Does not transfer; rebuild | Columns rebuilt without the filter logic |
Working from exported files after September 30, 2026
Microsoft Project Online retired on September 30, 2026. Microsoft has not committed to a read-only window, a grace period, or any post-retirement retention. Every step below therefore works from files you already hold: the .mpp or MSPDI XML per project, the OData CSVs from the export of your Project Online data, the SharePoint list extracts, and the screenshots and spreadsheets from your inventory. Where a step names an OData feed, read it as the CSV that feed produced; the column names are identical. Files you exported still import, with dependencies, custom fields and costs, and a .mpp or Project XML file imported into a new project brings its baseline as a baseline in Onplana. If a feed was never exported, the section for that object says what the file-based fallback recovers and what is gone.
Step 1, Inventory every custom field via OData
Before you can migrate anything you need a complete list. The PWA UI shows you fields one at a time; the OData feed gives you the whole catalog in one query. If your tenant no longer answers these queries, run the same steps against the CSVs your export pass produced; the columns are the same. The free Project Online Inventory Checklist frames this whole tenant-inventory step end to end. Custom fields are item 12 of 35, but the post-migration pain comes from the items most teams forget to count.
Pull the field definitions
GET https://your-tenant.sharepoint.com/sites/pwa/_api/ProjectData/CustomFields
Returns one row per defined field:
| Column | What it tells you |
|---|---|
Name |
Display name in the UI |
EntityTypeUID |
Project / Task / Resource attachment |
FieldType |
Text / Number / Date / Cost / Duration / Flag / Lookup |
LookupTableUID |
If non-null, the lookup table this field reads from |
IsMultiLineText |
Distinguishes single-line vs multi-line text fields |
IsRequired |
Whether the UI enforces a value |
Formula |
The calculated-field formula, if any |
RolldownToAssignments |
Whether task-level values cascade to assignment-level |
A typical mature Project Online tenant has 60–200 fields here. Save the result as a CSV, this becomes your migration manifest.
Pull the lookup-table values
GET https://your-tenant.sharepoint.com/sites/pwa/_api/ProjectData/LookupTables
GET https://your-tenant.sharepoint.com/sites/pwa/_api/ProjectData/LookupEntries
LookupTables gives you the table headers; LookupEntries gives you the values, one row per entry, with parent-child links via the MaskValue and ParentLookupEntryUID columns.
Hierarchical tables (cost centers, departments, phase codes) reveal themselves here. If MaskValue shows things like 01.02.03, you have hierarchy, flag the table for special handling in step 4.
Pull the per-task values
GET https://your-tenant.sharepoint.com/sites/pwa/_api/ProjectData/Tasks?$expand=CustomFields
Returns each task with its custom-field values inline. For large tenants paginate via $top and $skip, the feed throttles around 5,000 rows per call.
Step 2, Audit usage before you migrate
The single highest-impact thing you can do is delete unused fields on the source side before you start mapping. Most mature tenants find 40–60% of their custom fields are dead weight.
How to compute the coverage percentage
For each field in your inventory:
/* Pseudo-SQL against the OData feed (run as Power Query) */
SELECT
f.Name,
COUNT(v.TaskUID) FILTER (WHERE v.Value IS NOT NULL) * 100.0 / COUNT(t.TaskUID)
AS coverage_pct
FROM CustomFields f
JOIN Tasks t ON t.ProjectUID IN (SELECT ProjectUID FROM Projects WHERE Status = 'Published')
LEFT JOIN TaskCustomFieldsValues v ON v.TaskUID = t.TaskUID AND v.FieldUID = f.UID
GROUP BY f.UID, f.Name
ORDER BY coverage_pct DESC
For Project-attached fields swap Tasks for Projects. For Resource-attached, swap to Resources.
Cleanup decision rules
| Coverage | Decision |
|---|---|
| >50% | Keep, these drive your reports and PMs use them daily |
| 20–50% | Keep but mark for post-migration review, likely a "department-specific" field that one team uses |
| 5–20% | Judgment call, talk to the field owner before deciding |
| <5% | Retire on the source side, almost always a one-off field for a project that ended years ago |
The audit takes a day. The labor saved on mapping, validation, and documentation is typically two to three weeks for a mature PMO. There is no project where this audit doesn't pay for itself many times over.
Step 3, Snapshot calculated fields BEFORE you export
Calculated fields are the single biggest "lost in translation" item in any Project Online migration. The formulas use a Microsoft-proprietary expression language; no destination platform parses them, so the field arrives empty in the new tool.
The fix is dead simple
Snapshot the value into a regular static field before you export.
For each calculated field you want to preserve:
- Create a sibling stored field with the same data type. Name it the same as the calculated field plus
_Snapshot. - Populate it once via a Project Server PowerShell script or a manual Excel-OData round-trip:
# Pseudo-PowerShell: paste each calculated value into its sibling Get-SPProjectField -Name "CalcField" | ForEach-Object { Set-SPProjectField -Name "CalcField_Snapshot" -Value $_.ComputedValue } - Migrate the snapshot, not the formula. The new platform now has the value as static data.
- If you still want it live-computed, recreate the formula in the destination tool's expression engine after migration. About 60% of the time you discover you didn't actually need it live, it was a one-off categorization that the snapshot covers fine.
Why not just rewrite the formulas? You can, eventually. But rewriting on the destination side AFTER migration is ~5x cheaper than trying to do it in parallel with everything else during cutover. Snapshot first, rewrite the ones that matter later. Most don't.
Step 4, Map fields to the destination model
Every PM platform structures custom data slightly differently. Here's how Project Online's three-axis model maps to a typical modern destination.
| Project Online | Onplana equivalent | Notes |
|---|---|---|
| Project enterprise field | CustomFieldDefinition (entityType=PROJECT) |
1:1 mapping |
| Task enterprise field | CustomFieldDefinition (entityType=TASK) |
1:1 mapping |
| Resource enterprise field | User profile field | Modeled per-user, not per-task |
| Lookup table (flat) | DROPDOWN or MULTI_SELECT field | Values become options |
| Lookup table (hierarchical) | Tag tree with parent/child | Native parent-child support |
| Calculated field | Snapshot in static field | Re-create formula post-migration if needed |
| Multi-line text field | TEXT_LONG field type | Preserves line breaks |
| Cost field | NUMBER field with currency formatting | Currency conversion respects org default |
| Duration field | NUMBER (decimal hours) | Rolls up via task estimatedHours |
| Flag (boolean) | CHECKBOX field type | Maps cleanly |
Field-type fidelity
Five Project Online types have direct equivalents in Onplana's six-type custom-field system. The two edges:
- Cost fields that hold currency need an explicit currency code on the destination side. If your source field stored "$12,000" and your org runs multi-currency, lock the currency on the imported field to whatever the source project recorded, don't assume USD.
- Duration fields in Project Online store an integer count of "duration units" with a separate unit (hours, days, weeks). Onplana's NUMBER field is dimensionless; convert to hours at import time and document the conversion. Or model duration via
task.estimatedHoursinstead and skip the custom field entirely.
Hierarchical lookup tables, the special case
If your lookup table has parent-child entries (most cost-center and department codes do), you have two paths.
Pick Option A (flat dropdown) when the hierarchy is a UI grouping but reports never aggregate by parent. The flattened display name "01 Engineering / Backend" keeps the visual nesting; reports that need the leaf value just read the field as-is.
Pick Option B (Tag tree) when reports DO aggregate by parent, e.g. "show me total budget by Department, with sub-allocation by team." The tag tree keeps the parent-child relationship native, and Onplana's filter UI lets you scope a query by either level.
Step 5, Validate field values on the pilot
Migration is only successful if the values in the new platform match the source. For custom fields specifically the validation has three checks.
Coverage check
Did every source row that had a value end up with a value in the destination?
COUNT(non_null source values) == COUNT(non_null destination values)
If destination is lower, look at field-type mismatches first (most commonly: a Date field that arrived as TEXT because the destination didn't parse the source format). If destination is higher you have ghost values from a previous import, clear the destination first and re-run.
Type-fidelity check
For each field type, sample 10 rows and confirm:
- Number / Cost: precision is preserved (12.50, not 12.5 or 12)
- Date: timezone is preserved (date-only fields don't shift; timestamp fields land in UTC consistently)
- Multi-line text: line breaks survived
- Lookup: the imported value matches an existing option on the destination, not a free-text overwrite
Rollup check
If your source field had RolldownToAssignments = true, confirm the destination platform's equivalent rollup behavior matches. Some destinations (Onplana included) compute rollups on read rather than store them, the values you see in the destination's UI may not match the source's stored rollup but should match the source's displayed rollup.
The four traps that account for ~80% of "where did the data go?" tickets
After dozens of Project Online migrations, the same four issues come up again and again.
1. Resource custom fields modeled as task fields
Project Online lets you attach custom fields to Resources (e.g. "Skill Set"). On the destination side these usually need to land as user profile fields, not task or project fields. If you import them as task fields, every task ends up needing a "Skill Set" value entered manually, when the actual data wants to live on the assignee, not the work.
Fix: in step 4 of the inventory, sort by EntityTypeUID = Resource and route those rows to your destination's user-profile schema, not its custom-field schema.
2. Multi-value lookup fields collapsed to single-value
Project Online's MULTI_SELECT lookup field stores values as a delimited string ("OptionA;#OptionB;#OptionC"). If your importer reads each value as a single string, you end up with one option called "OptionA;#OptionB;#OptionC" instead of three separate selections.
Fix: pre-process the OData export to split on the ;# delimiter and emit one row per value. Do the split before you import; do not count on the importer to do it.
3. Calculated fields imported as static text, then "live-updated" by users
Once a snapshot is in the destination, users sometimes treat it as a regular field and start editing it. Six months later the values diverge from what the formula would have computed, and your reports start showing different numbers depending on whether they read the snapshot or recompute.
Fix: rename snapshotted fields with a _Snapshot or _AsOf2026-09-30 suffix on the destination side and lock them read-only. Re-create the formula as a computed view filter (or a destination-tool computed field if available) for live use; keep the snapshot as historical reference.
4. Currency-typed fields lose their currency
Project Online's Cost field type stores a number with implicit organization-default currency. After migration the value is just a number, if your org runs multi-currency, you've lost the currency context. Reports that mix projects across currencies start summing apples and oranges.
Fix: at import time, capture the source organization's default currency and tag every imported cost field's value with it. Onplana's import wizard does this automatically when the source project has a recorded currency; manual CSV imports need an explicit Currency column.
General field mapping rules: the order of operations and the two copies of every value
Project Online field mapping is four categories that fail differently, and the order you handle them decides whether values arrive: lookup tables first, field definitions second, project data third, calendars validated before you trust a date.
Every enterprise custom field value exists in two places. The .mpp carries the copy written into the schedule; the PWA reporting database carries a second copy, and the two diverge whenever a value was updated through a Project Detail Page form. Microsoft documents the schema in Enterprise Custom Fields and lookup tables in Project Web App. Where the copies disagree, the OData value is almost always correct, so the export pass needs both the .mpp files and a parallel pull of Projects?$expand=ProjectCustomFields and Tasks?$expand=CustomFields.
- Compare the OData values against the .mpp values for the same projects and record which fields disagree; those take their value from the CSV.
- Export the lookup library from Server Settings, Enterprise Custom Fields and Lookup Tables, and create every table in the destination before any import: a value whose option is missing either fails validation (visible) or imports as blank (invisible). Nested tables ("Division > Team > Sub-team") need a flatten-or-tree decision here.
- Create the field definitions, mapping each PWA type (text, number, cost, date, flag, duration) to a destination type and flagging every formula field for the snapshot step.
- Import the project data.
- Audit calendars before you read a date. A resource's effective calendar is three layers, the Enterprise Global Calendar, the project calendar and resource-specific exceptions, and every project whose calendar differs from the enterprise default shifts when a layer is lost. Onplana's import does not bring working or resource calendars across: the project uses the organization's working calendar, which you set up in Onplana before the import.
Validate with a three-column spreadsheet (field, source value, destination value) over four projects: one simple, one with nested lookups, one with several baselines, one with non-standard calendar exceptions. Any differing row is a gap; fix the import template and re-import.
Which of the eleven baselines transfer?
Project Online stores up to eleven baselines per project, Baseline (also called Baseline 0) through Baseline 10, and most migration paths carry exactly one. Baselines 1 through 10 hold approved scope changes, contract phases and audit reference points, and losing them is a compliance problem disguised as a technical default.
Set in the desktop .mpp, a baseline travels with the file in the fields Baseline Start, Baseline Finish, Baseline Work, Baseline Cost and Baseline Duration (numbered sets as Baseline 1 Start and so on). Set through the PWA Publish workflow, the common enterprise pattern, it lives in the reporting database and is authoritative in /_api/ProjectData/ProjectBaselines, one row per project and baseline number with start, finish, work and cost. A .mpp saved before the last Publish carries stale values.
For each baseline, ask four questions: is it referenced in a change control record, contract or audit document; is it the basis of a variance calculation in a current report; was it set at a formal approval event; does anyone know why it was set. One yes makes it a migration candidate; four nos make it an archive candidate, kept as CSV or PDF.
- Export the OData baseline snapshot for every project in scope to CSV, the archival record whether or not the destination accepts numbered sets.
- Classify each baseline with the four questions and mark the decision in the CSV.
- Test a multi-baseline import on one mid-complexity pilot; some destinations accept numbered baselines through MSPDI XML when they ignore them in a .mpp.
- After the full import, spot-check ten tasks per complex project: Baseline Start, Finish and Work in the destination against the OData export, for every migrated set, not only Baseline 0.
In Onplana, baselines with variance are on every plan including Free. Costs come across, and a .mpp or Project XML file imported into a new project brings its baseline as a baseline in Onplana; keep Baselines 1 to 10 from the file as the OData CSV. If a baseline is already missing after an import, Project Online baselines missing after a migration covers the repair.
How do the four dependency types survive export?
Finish-to-Start links survive migration in nearly every tool; Start-to-Start, Finish-to-Finish and Start-to-Finish links, and the lag on any of them, are the risk surface. Only a count by type proves anything.
Each dependency in the MSPDI export is a PredecessorLink record: predecessor task UID, successor UID, type (FS, SS, FF or SF) and an optional lag in days, hours or a percentage of the predecessor's duration, negative for a lead. The Project Online service description lists all four types. In our audit of Project Online schedules, roughly 40% of schedules with more than 200 tasks contained at least one non-FS dependency type, and above 500 tasks the share exceeded 60%.
Three failure modes do the damage: type collapse (SS, FF and SF links converted to FS or dropped, with no error), lag zeroed (a 3-day lag becomes 0 and a critical-path finish date shifts silently) and cross-project orphaning (a link into another project exists only in the enterprise, so the successor of a per-project export reschedules to as soon as possible).
- Export the dependency inventory per project: predecessor name, successor name, type, lag value, lag unit.
- Count links by type and by lag presence; these counts are the acceptance test.
- Flag every SS, FF or SF link with lag and every cross-project link for manual verification.
- Confirm the destination model with a small test schedule carrying all four types and mixed lag.
- After import, compare total counts (any reduction is a red flag), check a random 20% sample of non-FS links for type and lag, compare the critical-path task set in both tools, and look for newly unlinked tasks.
Repair follows the finding: rebuild converted links from the inventory; re-enter zeroed lag, critical-path links first; document cross-project links as external constraints; and if more than 15% of links changed, correct the MSPDI XML and re-import. Fixing broken dependencies after a Project Online migration walks that repair. Onplana keeps all four types with lag on every plan including Free and stores lag in days, so check any percentage lag after import.
Deliverables: the cross-project commitments no export carries
Project Online Deliverables are not tasks and are not in the schedule file: they are rows in a SharePoint list inside each project's PWA site, and no .mpp, MSPDI XML or standard OData project export includes them. One project publishes a task or milestone as a deliverable, a second project links to it, and PWA shows the commitment's status inside the consuming project's task views; Microsoft's service description lists deliverable management in Project Plan 3 and Plan 5.
Each record holds the source project and task identifiers, the consuming project and task identifiers, a status and a due date; the status is computed at render time, so the list stores the link, not the state.
- Pull the Deliverables list from every project site with PnP PowerShell or CSOM (a manual walk through the PWA Deliverables view works below about 25 projects), capturing both project names, both task names, status and due date.
- Keep only records where both the publishing and the consuming project are Active or On Hold; anything on a Closed or Archived project is an archive candidate.
- Confirm each consuming task still exists in that project's MSPDI export, so you know which destination task the rebuilt link attaches to.
- Match each active record to a pattern before cutover.
Pattern 1, a native cross-project dependency, is the highest-fidelity replacement and only worth a large rebuild if the destination propagates live status across projects. Pattern 2, a portfolio-level milestone tracker the consuming PMs watch, does not shift dates automatically but is fast to build. Pattern 3, a documented commitment in a project note or risk entry ("depends on Project B completing X by this date, checked in the Friday coordination call"), fits PMs who already coordinate directly.
In Onplana, Pattern 2 lands as milestones inside a portfolio (Business and above); verify Pattern 1 rather than assume it. Archive a record when both projects are closed, the deadline has passed, or the consuming task completed regardless. Validation: every active deliverable has a named landing point (a milestone, a portfolio view or a note) before cutover sign-off.
Cost fields and rate tables: five places, one sequence
Project Online cost data lives in five places, each with its own path: resource cost rate tables, Fixed Cost on tasks, baseline cost snapshots, actual cost derived from timesheets, and Enterprise Custom Fields of type Cost.
Every work resource in the Enterprise Resource Pool carries up to five date-tiered rate tables, A through E; Table A drives hours times rate by task date, and most organizations use only A. None of this is in the .mpp; it comes from Resources?$expand=CostRateTables. Baseline Cost travels with the baseline; Baseline Cost 1 through 10 matter only where an active report references them. ActualCost is derived, approved timesheet hours times the rate at the time of work, from the lines in /TimesheetLines. Cost-type ECFs hold budget, contingency and client billing amounts outside the schedule engine.
- Load the resource pool first, with Rate Table A and its date tiers for every resource on an active project; assignments imported before rates exist compute to zero cost. The resource model and Project Online Alternative Resource Management, Scored cover the pool itself.
- Export project data with Fixed Cost, Baseline Cost and the referenced numbered baselines, and validate them after import.
- Import cost-type ECFs once project data is stable, into a native budget field where one exists and a custom field otherwise.
- Decide the actuals: static ActualCost values keep totals right and lose the audit trail; full timesheet history keeps both and needs a destination that accepts line-level entries. Most organizations import full history for the current and prior fiscal year and static values for older periods.
- Validate cost totals for a sample of projects against the same summary from the OData export and investigate any discrepancy above tolerance.
Every Power BI report reading _api/ProjectData read the service live, and anything that read it live stopped with the retirement, per Microsoft's product lifecycle page; re-point them at the destination only after the cost migration is complete. In Onplana, rate cards carry one hourly cost rate per person, role or organization default, with effective date ranges that hold Table A's tiers, plus an optional billable rate or markup; time tracking, which produces actuals, starts on Pro.
Administrative time categories: the timesheet layer outside every project file
Administrative time categories are a timesheet artifact, not a project artifact: vacation, sick leave, training, bench time and company holidays that team members log hours against in PWA, configured under Server Settings, Time and Task Management, Administrative Time (see Microsoft's setup documentation). Each category carries a name, description, utilization flag and approval setting, and none of it touches a Gantt chart, a baseline or a critical path, which is why no .mpp or MSPDI export contains them.
Two OData feeds hold the data: AdminProject, with the category definitions, and TimeSheetLines filtered to administrative lines, joined to TimeSheetPeriods for period totals:
GET /ProjectData/TimeSheetLines?
$filter=TimeSheetLineClass eq 2
&$expand=TimeSheetPeriod,Resource
&$select=TimeSheetLineId,ResourceName,PeriodName,
TotalWork,ActualWork,AdminProjectName,Comment,StatusName
Run it in quarterly batches to stay under OData throttling and store the result as CSV or Parquet next to the AdminProject extract. The migration opens three gaps: configuration, history (leave and training records for HR audit or payroll reconciliation exist only in the extract) and process (people need to know where to log vacation on day one).
- Export
AdminProjectand the filteredTimeSheetLinesfirst; the configuration gap is recoverable, the history is not. - Consolidate the category list: twelve PWA leave types usually collapse to four or five without losing a report.
- Pick the pattern. Pattern 1 rebuilds the categories in the destination's own non-project time feature, if it shows in utilization reports. Pattern 2 routes HR-adjacent categories (vacation, sick leave, holidays) to the HRIS that already owns them and keeps bench and overhead in the PM tool. Pattern 3 creates one permanent Administrative Time project with a task per category, everyone assigned, filtered out of portfolio roll-ups.
- Configure approval to match the source rules and tell the team where to log before the first timesheet period opens.
Onplana attaches every logged hour to a task in a project, so Pattern 3 is the native fit, with time tracking starting on Pro. Validate by comparing hours per category per resource in the archive against PWA's final timesheet-period report. How to Move Off Project Online: The 6-Week Plan covers locked periods and approval history, which share the same OData dependency.
Do issues and risks survive the export?
No. Every project in Project Online has a SharePoint site with an Issues list and a Risks list holding the PMO's risk register, compliance findings and mitigation plans, and no .mpp, MSPDI XML or standard OData project query touches either list; Microsoft's service description lists issue and risk management in Plan 3 and Plan 5.
Extract from each Issues row: Title, Owner, Status, Priority, Category, DueDate, Description and ResolutionDetail, plus the discussion field holding the resolution history. From each Risks row: Title, Owner, Status, Probability, Impact, Mitigation, Contingency, DueDate and RelatedItems, the reference to a schedule task.
- Pull both lists from every project site with PnP PowerShell, CSOM or the REST API, one CSV per list per project.
- Classify each record: active (Open or In Progress on a project in flight), historical-closed (may be needed for audit) or stale-closed.
- Map the columns to the destination's field names and import the active records through its bulk import.
- Relink risks to tasks by name (add a related-task-name column to the export), critical-path tasks first; for closed risks, note the link in the description.
- Validate by counting open issues and open risks per active project in source and destination.
| Factor | Pattern 1: Rebuild in New Tool | Pattern 2: Spreadsheet Archive | Pattern 3: Keep in SharePoint |
|---|---|---|---|
| Best for | Active open items on in-flight projects | Historical closed records | Org staying on SharePoint post-migration |
| Level of effort | High (field mapping, import, validation) | Low (CSV export, organize) | Very low (leave in place) |
| Preserves active management | Yes | Manually only | No (view-only) |
| Integrated with schedule | Yes (if tool supports links) | No | No |
| Accessible after Sept 30, 2026 | Yes (in new tool) | Yes (in spreadsheet) | Depends on SharePoint subsite policy |
The usual outcome is Pattern 1 for active records and Pattern 2 for closed ones; Pattern 3 depends on the project sites surviving the PWA tenant cleanup, which Microsoft has not committed to. In Onplana, an Issues row maps to the issue log (Priority to severity, Category to type, Owner and DueDate to owner and target date) and a Risks row to the risk register, where accepting a risk creates its mitigation task; Project Risk Management: A Practical Guide for 2026 covers running the register from there.
Enterprise project types and templates: retire, rebuild or refactor
An Enterprise Project Template is a bundle, not a file: a base plan (.mpp or MSPDI) with the default WBS, Enterprise Custom Fields bound to the Project Detail Page, a working calendar, the PDP layout, a stage-gate workflow and the security settings that say who may create projects from it. Only the base plan exports. The bindings and PDP layout are admin metadata with no file format, and the workflow ran on SharePoint Workflow Foundation, which Microsoft retired on April 2, 2026, so every EPT workflow stopped before the tenant retired; what broke when SharePoint 2013 workflows retired covers that redesign.
The inventory lives at <PWA-URL>/pwa/_layouts/15/pwa/Admin/AdminEPTs.aspx. Record, per template: project type, the date a project was last created from it, whether it carries a workflow, the ECFs bound to its PDP, and the exported base .mpp. Then decide: retire it when no project was created from it in 12 months (archive the base .mpp); rebuild it when it is active with a simple or absent workflow (one to two days of configuration plus testing); refactor it when the workflow has conditional routing or parallel gates (three to five days for the workflow redesign first).
- Import the base .mpp, remove scaffolding tasks (placeholders, instructions to the PM) and save the result as the destination template.
- Bind the PDP's custom fields to the project form, required or optional as before.
- Set the default calendar: a migrated project calendar or the destination default.
- Configure the governance stages that replace the workflow: one gate per former stage, with exit criteria.
- Have a PM who works with that project type create a pilot project and push it through the first gate.
Three checks close the migration: a test project from every rebuilt template loads the structure, enforces required fields and picks the right calendar; a test proposal routes to the correct approver and records date and identity in the audit log; two templates sharing a custom field both show and store it. In Onplana, the imported base plan saves as a project template (templates start on Professional), and the governance pipeline supplies the gates, Proposal Review, Business Case Review and Plan Review, each scored against weighted evaluation criteria.
Permissions and groups: PWA security categories to roles
Project Online permissions are a category model, not a role model, and that is where bulk mappings fail. A security category groups users by their relationship to a project or the PMO, with a security template listing the allowed actions; the defaults are Project Managers, Team Members, Resource Managers, Portfolio Managers, Team Leads, Executives and Administrators, and membership is dynamic, so one person holds Project Manager rights on projects they manage and Team Member rights where they hold assignments. Modern tools assign a fixed organization role plus a fixed project role, so a bulk "everyone becomes a Member" mapping leaves project managers unable to create tasks, and custom categories for departments, vendors and external stakeholders need individual review. The export is a screen, not a feed: document Manage Categories, Manage Groups and Manage Security Templates in full.
| PWA security category | Onplana destination |
|---|---|
| Administrators (two or three real ones, after pruning) | Owner or Admin |
| Portfolio Managers, Executives with all-project visibility | Portfolio Manager |
| Project Managers | Project Owner or Project Manager on their own projects |
| Team Members who edit tasks | Project Member or Project Contributor |
| Status reporters, auditors, read-only stakeholders | Project Viewer |
| External vendors with scoped access | Guest, added only to their projects |
| Custom categories with unusual combinations | Custom project roles (Business and above), reviewed one by one |
- Create a test account for each role in the mapped model.
- Confirm each account can open its projects, see its dashboards and edit tasks in the right scope.
- Confirm each account cannot see projects outside its scope, org-wide reports it is not entitled to, or admin settings.
- Test the edge cases: a PM who is also a team member on a colleague's project.
- Record the results and get PMO sign-off before go-live.
Prune before you replicate: a mature tenant that should have two or three administrators often has fifteen or twenty, so apply least privilege before the list is copied. Onplana resolves permissions along two axes, an organization role (Owner, Admin, Portfolio Manager, Member, Guest) and a project role (Project Owner, Manager, Member, Contributor, Viewer), and how Onplana protects your project data covers the audit side.
Portfolio objects and prioritization: rebuild the engine, archive the output
Migrating the projects does not migrate the portfolio. Business drivers, driver weights, strategic scores, scenario models and the portfolio-program-project hierarchy are administrative configuration in the Plan 5 Portfolio Analyzer, not project data; none of it is in a .mpp or an OData pull, and the projects arrive as a flat list.
| Component | Migration path | Notes |
|---|---|---|
| Business driver definitions + weights | Rebuild | Document current drivers before cutover; rebuild in destination |
| Project scores per driver | Export to CSV via OData | Use as reference when rebuilding scores in destination |
| Strategic score per project | Export to CSV via OData | Portable as a snapshot; recalculate once drivers are rebuilt |
| Saved scenario models | Export to PDF or presentation | Historical decision records, not live data |
| Portfolio/program hierarchy | Rebuild | Map to destination tool's structure before migration |
Portfolio configuration is system implementation with the old system as the specification, and it typically adds four to eight weeks beyond the project import. The specification needs five parts: every driver with its description and weight; the 0-to-10 scoring rubric with each point defined; every portfolio and program with owner, member projects and visibility rules; every saved scenario with its constraint, selected projects and score total; and every dashboard the portfolio drives. The hierarchy has three destination shapes: a flat list with tags, a native hierarchy rebuild, or a pragmatic reset around current strategy, common because most PWA hierarchies mirror the org chart of the year the tenant was configured.
- Export hierarchy, drivers, weights, scenario snapshots and strategic scores.
- Import the project data.
- Configure portfolios and programs in the destination.
- Rebuild the drivers and the scoring rubric.
- Assign the imported projects to their portfolio and program.
- Re-score every project against the rebuilt model.
- Validate: the new scores should correlate with the archived scores without matching exactly, because a rebuilt model corrects undocumented weight drift.
- Archive the scenario models as decision records; recreating them in a new tool invites decisions on stale context.
In Onplana, portfolios start on Business, and the weighted evaluation criteria configured per governance gate are where business drivers land. Migrating Project Online portfolio prioritization models goes deeper on the scoring rebuild.
Page customizations and Project Detail Pages: rebuild from a documented spec
Every PWA page is a SharePoint page assembled from web parts, and every Project Detail Page is a SharePoint page whose web parts display specific enterprise custom fields. Both are page metadata, not project data: no .mpp, XML or OData export carries them, a PnP export documents but cannot import them, and no migration tool reads them. The most customized web parts are the Project Center grid, the Gantt web part, the Resource Center, the milestone rollup, the status report summary and the portfolio analysis views; a PDP adds the set and order of fields on the project forms, which the template rebuild recreates as bindings.
- Identify the pages used at least weekly: the Project Center home, the main utilization view, the home pages of active projects.
- For each web part on those pages, record type, data source, columns, filters, groupings and position; an annotated screenshot becomes the acceptance criterion.
- Record the primary audience: a PMO director's portfolio-by-program view and a resource manager's utilization-by-role view are different rebuilds.
- Tier the list: must exist before the first working day in the new tool, needed within 30 days, or whenever time allows.
- Build the tier-one pages against real data from the pilot import and have each page's audience review them.
| PWA Web Part | Modern PM Tool Equivalent |
|---|---|
| Project Center (portfolio grid) | Portfolio list view with configurable columns and grouping |
| Gantt chart web part | Gantt view with program rollup option |
| Resource Center (availability) | Resource availability or capacity panel |
| Resource Center (workload) | Resource utilization heatmap or workload chart |
| Milestone rollup | Status dashboard with milestone filter |
| Status report summary | Status report feed or recent updates widget |
| Portfolio analysis view | Scenario planning or portfolio comparison view |
| Project home page | Per-project overview page with section layout |
The rebuild is a rationalization, not a replica: years of administrators leave views nobody opens and filters on deleted fields, so ask each audience what they need rather than copying what existed. Validation: every tier-one page has a working equivalent its primary audience has reviewed before anyone depends on it. In Onplana, pages built from web parts and dashboards start on Pro.
Views and filters: table, filter, grouping and sort
Project Online views never migrate: a view is site configuration stored as XML in the PWA site collection, one layer above the project data every export reads. A view is a table (columns, order, width), a filter (rows), a grouping and a sort order, and one table underlies many views. Rebuild only the column list and a view filtered to Resource Name equals [Me] and Finish Date less than Today shows every task in the project.
Enterprise views live under PWA Settings, Look and Feel, Views, as Task, Project, Resource and Assignment views; Project Center views sit under Look and Feel, Project Center; project-level views that PMs customized appear in no admin list, so open representative projects and inspect the view menu. Per view, the inventory carries name, category, table, filter definition, group by, sort by, primary users and a priority rank, the rank set by one question put to five PMs: which three views do you open in the first 30 minutes of every workday.
| Priority | View type | Examples | Rebuild when |
|---|---|---|---|
| P1 | Daily task sheets | Weekly edit view, My Tasks, critical path filter | Before any PM logs in |
| P2 | Project Center views | PMO dashboard, executive summary, department filter | Before the first steering meeting |
| P3 | Resource views | Resource usage, overallocation, availability by period | Before the first capacity review |
| P4 | Portfolio analysis | Portfolio Analyzer, scenario comparison, strategic priority | After data validation, as a process redesign |
- Confirm the view's tier in the inventory.
- Create the view from its column set, mapping each field to the destination schema; any custom field it uses must already exist.
- Translate the filter (field, operator, value), keeping [Me], Today and This Week dynamic.
- Add the grouping and sort order.
- Validate against three to five representative projects: the rebuilt view returns the rows the source view returned.
Three view types have no direct equivalent: resource usage views become a heatmap or utilization chart; Portfolio Analyzer views need a portfolio dashboard built differently; timesheet-linked views belong to the timesheet plan. Park any view without a current user. In Onplana, filter and sort combinations on the Projects page save as named views, dashboards start on Pro, and a filter on a custom field needs that field created first (custom fields start on Pro).
Migrating to Onplana specifically
If Onplana is the destination, the custom-field path is paved:
- File import, not OData: Onplana imports .mpp and Project XML files, plus .mpx, Primavera P6 .xer, ProjectLibre .pod, GanttProject .gan and Excel or CSV, up to 50 MB, on every plan. Custom field values in the file come across. There is no OData import, so set up the field definitions and lookup options from your OData CSVs before you import.
- Currency lock: Cost fields inherit the source project's currency; nothing collapses to a generic number.
- Tag-tree hierarchy: hierarchical lookup tables can be rebuilt as a Tag tree, preserving parent-child relationships for filtering.
- Plan gating: the schedule side of an import (tasks, the Gantt, the critical path and all four dependency types with lag) lands on every plan including Free. Baselines with variance are on every plan too, and a .mpp or Project XML file imported into a new project brings its baseline as a baseline in Onplana. Custom fields, time tracking, dashboards and resource capacity planning start on Pro, and portfolios start on Business, so run the custom-field pass in a Pro workspace and the portfolio rebuild in a Business one.
Where to go deeper
- How to Move Off Project Online: The 6-Week Plan, the migration plan this post fits into
- Cost of Migrating from MS Project Online in 2026, custom fields are the biggest variable in the data-migration line item
- Project Online Migration Checklist 2026, printable cutover checklist
- Project Online Retirement: Dates, What Stops, What to Export, the consolidated reference for the three 2026 retirement dates
- MS Project Migration Compatibility Audit 2026, the source-side diagnostic to run before exporting
Inventory the rest of your tenant before you export Custom fields are 1 of 35 items most migrations underestimate. The free Project Online Inventory Checklist walks every category (projects, resources, custom fields, integrations) with notes, owners, and PDF export. → Open the inventory checklist
Need help with a specific custom-field shape that this post didn't cover? Get in touch, we've seen most of them and can usually point you at the right destination model in 10 minutes.
Microsoft Project Online™ is a trademark of Microsoft Corporation. Onplana is not affiliated with Microsoft.
Frequently asked questions
Do Project Online calculated fields migrate?
The formulas do not migrate, but the last computed value does. Snapshot each calculated value into a static text or number field before you export, move the snapshot as data, and recreate only the formulas you still need in the destination's expression engine.
Should I bring across every custom field, or audit first?
Audit first, on the source side. Mature tenants carry 60 to 200 enterprise custom fields and typically 40 to 60 percent are unused or duplicated, so run a coverage report (how many tasks or projects hold a non-null value) and retire anything below 5 percent before you map it.
Do Enterprise Custom Fields travel in a .mpp export?
Partly. Values written into the schedule file travel in the .mpp ExtendedAttribute data, but values entered through Project Detail Pages and stored only in the PWA reporting database do not, so the OData ProjectData feeds are the authoritative copy for those.
How many baselines does Project Online store, and do they all migrate?
Up to 11 per project, Baseline (also called Baseline 0) through Baseline 10. Baselines set in the desktop file travel with the .mpp; baselines set through PWA Publish live in the reporting database and exist only in an OData ProjectBaselines export, and most importers keep only the active baseline.
Do all four Project Online dependency types and their lag values migrate?
Only when the destination supports them: FS links survive almost everywhere, while SS, FF and SF links and their lag values are what degrade. Onplana keeps all four types with lag on every plan including Free; verify by counting dependencies by type in the source and again in the destination.
Do resource cost rate tables migrate automatically?
No. Rate tables belong to the Enterprise Resource Pool, not the .mpp file, so export them from the OData Resources feed with the cost rate tables expanded and load Rate Table A, with its date tiers, as per-user rate cards before you import assignments.
Do issues, risks and deliverables survive a .mpp export?
No. All three live in SharePoint lists inside each project's PWA site, so no .mpp, MSPDI XML or standard OData project export includes them; you extract the lists with PowerShell or the SharePoint REST API and import the active records into the destination's issue log and risk register.
Do Project Online views, page customizations, permissions and portfolio settings migrate?
No. Views, filters, web-part layouts, security categories, business drivers and portfolio hierarchy are PWA site configuration with no import path into any other tool, so you document them from the inventory you took before the export and rebuild them in the destination.
Ready to make the switch?
Start your free Onplana account and import your existing projects in minutes.