DataMigrationToolbyXTB 1.2026.6.2
dotnet add package DataMigrationToolbyXTB --version 1.2026.6.2
NuGet\Install-Package DataMigrationToolbyXTB -Version 1.2026.6.2
<PackageReference Include="DataMigrationToolbyXTB" Version="1.2026.6.2" />
<PackageVersion Include="DataMigrationToolbyXTB" Version="1.2026.6.2" />
<PackageReference Include="DataMigrationToolbyXTB" />
paket add DataMigrationToolbyXTB --version 1.2026.6.2
#r "nuget: DataMigrationToolbyXTB, 1.2026.6.2"
#:package DataMigrationToolbyXTB@1.2026.6.2
#addin nuget:?package=DataMigrationToolbyXTB&version=1.2026.6.2
#tool nuget:?package=DataMigrationToolbyXTB&version=1.2026.6.2
DataMigrationToolbyXTB
An XrmToolBox tool that migrates records from one Dataverse environment to another while preserving the record GUID. A record that does not exist on the target is created with the same Id; a record whose Id already exists on the target is updated.
This is ideal for moving configuration / reference data (and any GUID-sensitive records) between DEV → TEST → PROD without breaking the lookups and references that depend on those Ids.
The tool's display name in XrmToolBox is DataMigrationToolbyXTB; the compiled assembly is
DataMigrationToolbyXTB.dll.
Features
- Two-environment workflow – select a Source and a Target connection independently, using the standard XrmToolBox connection picker.
- Entity picker from the Default solution – loads the entities contained in the source environment's Default solution into a dropdown.
- FetchXML-driven selection – you supply the FetchXML that decides exactly which records are migrated. A starter template is generated automatically when you pick an entity.
- GUID preserved – records keep their primary key across environments (create-with-Id / update-by-Id).
- Schema-aware writes – read-only columns (calculated/rollup, audit, and other non-writable
system fields) and link-entity (
AliasedValue) columns are skipped automatically so writes don't fail. - Optional ownership – migrate
ownerid(off by default). - Optional status – migrate
statecode/statuscodeusingSetStateRequest(a proper, supported state transition), applied after the record is written (off by default). - N:N associations – optionally replicate many-to-many relationship links (the rows behind an
associated view subgrid) on the target via
Associate. You pick which relationships to include per entity. - Robust paging – source queries are paged automatically (handles > 5000 records).
- Progress, cancel, and a full log – created / updated / failed counts plus per-record errors.
Requirements
- XrmToolBox (current release – runs on .NET Framework 4.8).
- Permissions on both environments: read on the source, create/update (and, for status migration, the relevant state-transition privileges) on the target.
Build
Open MigrateData.sln in Visual Studio 2022 and build, or from a developer prompt:
& "C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe" `
MigrateData.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU"
A Debug build copies DataMigrationToolbyXTB.dll (+ .pdb) into
DataTransPorter\bin\Debug\Plugins\ via the post-build step.
The XrmToolBox host assemblies (
XrmToolBox.Extensibility,XrmToolBox.ToolLibrary,McTools.Xrm.Connection,McTools.Xrm.Connection.WinForms) are referenced withPrivate=False– they are provided by the host at runtime and are not copied to the output, which avoids version conflicts.
Install into XrmToolBox (manual / local)
Copy DataMigrationToolbyXTB.dll into your XrmToolBox Plugins folder, then restart XrmToolBox:
%APPDATA%\MscrmTools\XrmToolBox\Plugins
The tool appears in the tool list as DataMigrationToolbyXTB.
Publish to the XrmToolBox Tool Library (public)
XrmToolBox's in-app Tool Library (Configuration ▸ Tool Library) is fed from NuGet.org. A package is auto-discovered and installable for everyone when it:
- is tagged
XrmToolBox, - ships the tool assembly under
lib\<tfm>\Plugins\(third-party dependency DLLs, if any, go in a sub-folder named exactly like the tool DLL), and - declares a dependency on the
XrmToolBoxpackage (the host-version marker).
This repo already contains everything for that: DataMigrationToolbyXTB.nuspec
and pack-and-publish.ps1.
One-time setup
- Create a free NuGet.org account and an API key: https://www.nuget.org/account/apikeys (scope it to Push new packages and package versions).
- Edit
DataMigrationToolbyXTB.nuspecand set:<id>– must be globally unique on NuGet.org (currentlyDataMigrationToolbyXTB). It must not collide with another package, and the tool DLL name (DataMigrationToolbyXTB.dll) must not collide with another installed tool.<authors>,<projectUrl>,<iconUrl>,<license>– your details. (<iconUrl>must point at a publicly reachable copy ofimages\icon.png, e.g. the raw URL in your GitHub repo.)- The icon (
images\icon.png) and tool tile images are already wired in.
Build, pack and publish
# build + pack only (inspect artifacts\*.nupkg first)
.\pack-and-publish.ps1
# build + pack + publish to NuGet.org
.\pack-and-publish.ps1 -Push -ApiKey oy2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
After NuGet finishes indexing (a few minutes) the tool shows up in the Tool Library; users click Install. There is no separate approval step, but the package must pass NuGet's validation and follow the three rules above.
Publishing requirements checklist
- ✅ Tagged
XrmToolBox(first tag). - ✅ Tool DLL in
lib\net48\Plugins\(the pack script + nuspec do this). - ✅ Dependency on
XrmToolBox(host-version marker). - ✅ Assembly is not strong-named (this project isn't).
- ✅ Unique NuGet
idand unique tool DLL name. - ✅ Host assemblies (
XrmToolBox.Extensibility,McTools.Xrm.Connection, Xrm SDK) are not bundled — they're referenced withPrivate=Falseand provided by the host at runtime.
Releasing updates
NuGet package versions are immutable — you cannot overwrite a published version. To update,
bump <version> in the nuspec and AssemblyVersion/AssemblyFileVersion in
Properties\AssemblyInfo.cs (keep them equal; date-based 1.YYYY.M.rev is the XrmToolBox
convention), re-run pack-and-publish.ps1 -Push -ApiKey …, and XrmToolBox offers the update
automatically.
XrmToolBox Tool Library validation checklist
How this package/tool satisfies the official Tool Library checklist:
| Checklist item | Status | How |
|---|---|---|
| NuGet package has an icon url | ✅ | <iconUrl> + embedded <icon> (images\icon.png) in the nuspec. Set <iconUrl> to your public raw URL. |
| NuGet package has a project url | ✅ | <projectUrl> in the nuspec (set it to your repo). |
Tool library under a Plugins folder |
✅ | DLL packed to lib\net48\Plugins\DataMigrationToolbyXTB.dll. |
| Tool version = NuGet package version | ✅ | AssemblyVersion/AssemblyFileVersion = 1.2026.6.2 = <version>. |
| Dedicated large tool image | ✅ | BigImageBase64 (80×80) in MyPlugin.cs. |
| Dedicated small tool image | ✅ | SmallImageBase64 (32×32) in MyPlugin.cs. |
| Controls resize with the main window | ✅ | Docked TableLayoutPanel with percentage rows; editors Dock=Fill; inputs anchored. |
| Tool opens without a connection | ✅ | OnLoad never requires Service; no connection is forced. |
| Without connection, controls work without error | ✅ | All handlers null-check the services and guide the user. |
| Connection-required controls open the connection dialog | ✅ | Select Source/Select Target raise the connection request; Load/Count/Migrate open it when no connection is set. |
| With a connection, controls work without error | ✅ | Standard ExecuteMethod/WorkAsync + IOrganizationService calls. |
| Long operations are async (UI not frozen) | ✅ | Every server operation runs in WorkAsync with progress + cancel. |
The images are stored as source PNGs under
images\(icon.png,tool-large.png,tool-small.png); the 80×80 and 32×32 are base64-embedded inMyPlugin.cs. Regenerate by replacing the PNGs and updating the two…ImageBase64strings.
Usage
- 1. Select Source – choose the environment to read records from. (The connection you are already on when you open the tool is used as the source by default.)
- 2. Select Target – choose the environment to write records to.
- 3. Load Entities – populates the dropdown with entities from the source Default solution.
- Pick an entity. A default FetchXML template is placed in the editor, and the entity's many-to-many relationships load into the N:N associations list.
- 4. FetchXML – edit the FetchXML to select exactly the records you want to migrate. Use Count source records to preview how many records match.
- (Optional) In the N:N associations list, check any relationships whose links you want replicated on the target.
- 5. Migrate Data – confirm the prompt. Each record is created (same GUID) or updated; then, for
each checked relationship, the links are replicated via
Associate. The log shows a summary.
Options
| Option | Default | Behaviour |
|---|---|---|
| Migrate owner (ownerid) | off | When on, the source ownerid is written to the target. The referenced user/team must exist on the target. |
| Migrate status (state/status via SetState) | off | When on, after the record is written the source statecode/statuscode is applied via SetStateRequest. Failures are reported as warnings (the record itself still migrates). |
| Continue on error | on | When on, a failing record is logged and migration continues. When off, migration stops at the first failure. |
FetchXML examples
Migrate every record of the chosen entity:
<fetch>
<entity name="mash_service">
<all-attributes />
</entity>
</fetch>
Migrate a filtered subset:
<fetch>
<entity name="mash_service">
<all-attributes />
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
<condition attribute="mash_category" operator="eq" value="100000001" />
</filter>
</entity>
</fetch>
Use
<all-attributes />(rather than naming columns) so every migratable field is carried over. Columns that cannot be written (calculated, rollup, audit, etc.) are filtered out automatically against the target schema.
How GUID preservation works
For each source record the tool:
- Builds a target
EntitywithId = source.Idand the migratable attributes. - Calls
Retrieve(target, id, ColumnSet(false))to check existence.- Not found (
ObjectDoesNotExist,0x80040217) →Create(entity)– Dataverse honours the suppliedId, so the record is created with the same GUID. - Found →
Update(entity).
- Not found (
Notes & limitations
- Reference order – references (lookups) resolve by GUID. If a record points to another record that has not been migrated yet, that write fails. Migrate parent/lookup entities first, or run the migration twice (leave Continue on error on for the first pass).
- N:N associations – only links where the migrated record is one side are replicated, and the
other side must already exist on the target (otherwise that link is reported as failed). Links
that already exist on the target are detected and counted as "already linked" (idempotent).
Self-referential N:N is handled best-effort using the
Referencingrole. - Status –
statecode/statuscodeare never written as part of the create/update; they are applied separately viaSetStateRequest. A status reason of-1lets the platform pick the default status for the chosen state. - Owner / business unit – owning business unit/team/user are system-managed and are never
copied; only
owneridis migrated, and only when the option is enabled. - Counting loads the matching records to count them; for very large tables prefer a tight FetchXML filter.
Project layout
| File | Purpose |
|---|---|
DataTransPorter/MyPlugin.cs |
XrmToolBox tool export (name, description, tile images). |
DataTransPorter/MyPluginControl.cs |
All tool logic (connections, entity load, migration). |
DataTransPorter/MyPluginControl.designer.cs |
WinForms UI. |
DataTransPorter/Settings.cs |
Persisted options / last selections. |
DataTransPorter/DataTransPorter.csproj |
Project + references (targets .NET 4.8; AssemblyName = DataMigrationToolbyXTB). |
DataMigrationToolbyXTB.nuspec |
NuGet package manifest for the Tool Library. |
pack-and-publish.ps1 |
Build → pack → (optional) publish helper. |
images/ |
icon.png (package icon) + tool-large.png / tool-small.png (tile sources). |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET Framework | net48 is compatible. net481 was computed. |
-
.NETFramework 4.8
- XrmToolBox (>= 1.2025.10.74)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|
1.2026.6.2 - GUID-preserving record migration (create/update by Id), default-solution entity picker, FetchXML selection with paging, optional owner and status (SetState) migration, selectable N:N association replication. Adds tool tile images, package icon and embedded readme.