Every ITSM migration is a small archaeology project. Ten years of ticket history, three or four generations of custom fields, a half-forgotten SLA rule that only applies during the fiscal year-end freeze — all of it has to survive the move, or the operations team loses institutional memory. This guide is written for the engineer or IT manager who has been handed a ManageEngine Service Desk Plus (SDP) instance and told to move it to LinaDesk before the next renewal cycle.
We assume you have SDP on-premise (Build 14xxx or 15xxx), somewhere between 5,000 and 200,000 historical tickets, an Active Directory-backed user store, and a small handful of email/LDAP integrations. If your SDP is the MSP edition or you are running Enterprise with the CMDB module heavily populated, some of the mapping below will need to be extended — the shape of the work stays the same.
Why organizations migrate off SDP
Before the mechanics, the reasons — because they shape the mapping decisions later. In practice, teams initiating an SDP-to-LinaDesk migration land on one or more of the following:
- KVKK and data residency. SDP's cloud edition sits on Zoho infrastructure outside Turkey. Its on-premise edition is fine on that front, but the licensing model funnels customers toward cloud at renewal. Turkish organizations bound by KVKK Article 9 (cross-border transfer) prefer a Turkish-controlled on-premise vendor as insurance against forced cloud migration.
- Per-technician cost trajectory. SDP's price per technician has increased steadily since 2022, and the modular pricing (add-ons for change, project, CMDB) accumulates. A fixed-license alternative removes renewal-time surprises.
- UI and keyboard-shortcut ergonomics. SDP's UI predates Linear-era design norms. Teams whose L1 technicians live in the queue all day feel this daily.
- Air-gap or classified-network deployments. Government and defense customers cannot run SDP's cloud add-ons; every capability they want must run inside their perimeter.
The reason matters because it dictates what gets carried across. A KVKK-driven migration typically preserves everything, because auditors will ask. A cost-driven migration will happily leave behind features nobody uses.
Phase 1 — Discovery (2 weeks)
The discovery phase exists to prevent the two worst outcomes of an ITSM migration: missing data that turns out to matter and migrated data that turns out to be junk. Two weeks feels long — it is not.
Inventory the SDP instance
Take an honest inventory. From the SDP admin console, capture the following in a shared spreadsheet:
- Total request count, split by status (Open, On Hold, Resolved, Closed) and by year of creation.
- All request templates in use — including the ones nobody remembers who created.
- All custom fields, per module. Note the field type, whether it is mandatory, and which templates reference it.
- All SLA policies, with their business hour definitions, escalation levels, and matched criteria.
- All automation rules (Business Rules, Field & Form Rules, Custom Triggers, Time Triggers).
- All email templates and notification rules.
- All approval workflows.
- All roles, with permission mappings.
- Every integration: LDAP/AD, email servers, SCCM/probes, third-party APIs.
The output is not a document — it is a decision list. Every item is tagged bring, rebuild, or drop. A rule of thumb: if fewer than three tickets in the last twelve months have used a template or custom field, it is a candidate to drop.
Interview the operations team
Discovery is not just an admin-console walk. Sit with three L1 technicians, one L2 lead, and the service desk manager. Ask which reports they open weekly, which macros they use, and which fields they habitually leave blank. The dashboards nobody opens are the fields nobody needs.
Map integration dependencies
SDP is often the hub for adjacent systems: a monitoring tool posts alerts as tickets, an asset-scanner writes CI records, a payroll integration triggers HR onboarding requests. Each of these has to be either re-pointed at LinaDesk's API or paused during cut-over. Miss one and Monday morning brings a stack of orphaned tickets.
Phase 2 — Data mapping
SDP's data model and LinaDesk's are cousins, not twins. The table below is the mapping we use as a starting point; customization always adds rows.
| SDP entity | LinaDesk entity | Notes |
|---|---|---|
| Requesters | Users (role: EndUser) | Map on UPN, not on internal user_id — see AD section. |
| Technicians | Users (role: Technician) | Preserve the technician-group membership as LinaDesk Teams. |
| Groups | Teams | SDP's Support Group ↔ LinaDesk Team is a clean 1:1. |
| Requests | Tickets | Preserve original CreatedAt as CreatedAtUtc (see backdating). |
| Request notes | TicketComments | Private/public flag maps directly. |
| Request attachments | Attachments | Blob storage location changes; URLs in note bodies must be rewritten. |
| Assets | Assets | SDP's ProductType ↔ LinaDesk AssetCategory. |
| Asset Additional Fields | CustomFields (scope=Asset) | Type mapping: SDP text → LinaDesk string; SDP picklist → LinaDesk enum. |
| Solutions (KB articles) | KnowledgeArticles | Approval status flag preserved. |
| Categories / Subcategories / Items | Category tree (nested) | LinaDesk uses a single nested tree; SDP's three-level split is flattened into a path. |
| SLA Policies | SlaPolicies | Business hours moved to WorkCalendar; see SLA section. |
| Business Rules | Automations | Rewrite required — no direct import. |
| Change requests | Changes | CAB approval chains rebuilt in LinaDesk's ChangeApproval flow. |
The rows that require the most engineering time, in our experience, are custom fields, categories, and SLA policies. Everything else is mechanical.
Phase 3 — Export
SDP has three ways to get data out: the built-in scheduled exports, the REST API v3, and direct database access. All three have a place.
The REST API v3 for structured data
The API is the correct source for users, technicians, groups, categories, SLA policies, and any entity you need with its full field set. The endpoints are stable, they respect pagination, and they return JSON that maps cleanly onto our target schema.
A minimal PowerShell script to pull all requests, page by page, into a directory of JSON blobs:
# requires SDP TECHNICIAN_KEY with read access
$sdpUri = "https://sdp.internal/api/v3/requests"
$authKey = $env:SDP_TECHNICIAN_KEY
$outDir = "C:\migration\raw\requests"
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
$rowsPerPage = 100
$rowIndex = 1
do {
$inputData = @{
list_info = @{
row_count = $rowsPerPage
start_index = $rowIndex
get_total_count = $true
fields_required = @(
"id","subject","description","status","priority",
"created_time","resolved_time","closed_time",
"requester","technician","group","category","subcategory","item",
"udf_fields")
}
} | ConvertTo-Json -Depth 6 -Compress
$resp = Invoke-RestMethod `
-Uri "$sdpUri?input_data=$([uri]::EscapeDataString($inputData))" `
-Headers @{ "authtoken" = $authKey } `
-Method GET
$resp.requests | ForEach-Object {
$_ | ConvertTo-Json -Depth 12 |
Out-File -Encoding utf8 "$outDir\req_$($_.id).json"
}
$total = $resp.list_info.total_count
$rowIndex += $rowsPerPage
} while ($rowIndex -le $total)
The equivalent scripts for users, groups, and assets are structural copies. Keep them under version control — you will run them at least three times: once during dry-run, once during rehearsal, once during cut-over.
Direct database read for archived attachments
SDP stores attachments outside the request payload. The API returns metadata but not blobs. For the actual bytes, either use the file-attachment endpoint per record (slow, but respects permissions) or read from SDP's FileAttachment table plus the on-disk Attachments directory. On large instances (100k+ tickets with attachments), the second is the only realistic option — plan an overnight rsync.
Phase 4 — Ticket history preservation
The single most important field in the migration is CreatedAtUtc. If it silently defaults to now, ten years of history compress into a single day and every SLA report becomes meaningless.
LinaDesk supports backdated ticket creation via its bulk-import endpoint. The rule:
Every ticket, comment, status transition, and audit entry carries its original UTC timestamp. Nothing in the import path is allowed to overwrite it.
Concretely: SDP's created_time.value is a Unix millisecond string. Convert to UTC ISO-8601 and pass it as CreatedAtUtc. Do the same for resolved_time, closed_time, and each individual note's created timestamp. If a note has an updated_time that differs from its created_time, preserve both — audit teams occasionally check.
A subtle trap: SDP's timestamps are stored in the account timezone but reported by the API in UTC only if the technician key's user has UTC as its display timezone. Verify this once against three known records before you trust the whole export.
Phase 5 — AD / LDAP re-mapping
Users are almost always the hardest join in the migration. SDP identifies a user internally by its REQUESTERID. Active Directory identifies the same person by their objectGUID. LinaDesk uses ExternalId (which we recommend setting to the AD objectGUID).
The migration cannot rely on either primary key alone. The join we use, in priority order:
- UPN (userPrincipalName). This survives AD renames and cross-forest moves. Use as the primary join.
- Email address. Falls back if UPN is missing.
- sAMAccountName. Last resort, because it is not guaranteed unique across forests.
Any user that fails all three joins goes into a orphans.csv file. In every real migration we have run, this file has between 20 and 400 rows — people who left the company, service accounts that were never linked to AD, and requesters who submitted a single ticket via email in 2018. Decide their fate manually. Do not skip this step: those orphans still own historical tickets and their names must appear correctly in reporting.
Phase 6 — SLA policy remapping
SDP's SLA model is a flat rule engine: match by request criteria, apply response/resolution windows against a business-hour calendar. LinaDesk's model is close but not identical:
- SDP's Operational Hours ↔ LinaDesk's
WorkCalendar. - SDP's Holidays ↔ LinaDesk's
WorkCalendarHoliday. - SDP's SLA criteria ↔ LinaDesk's
SlaPolicyMatchconditions. - SDP's Escalation levels ↔ LinaDesk's
SlaEscalationchain.
The one meaningful gap is around partial pauses. SDP allows SLA to be paused when the ticket is Waiting for Requester. LinaDesk requires the same behavior to be modeled as an explicit PauseOnStatus array in the SLA policy. Do the mapping in the migration script rather than hoping the defaults line up — every SDP instance we have looked at had at least one non-default pause status.
For a longer discussion of the calendar side of SLA design, see the SLA calendar design post — the modeling decisions there apply directly to how you rebuild the calendar in LinaDesk.
Phase 7 — Portal, branding, notification templates
These do not migrate. They rebuild.
SDP's self-service portal is a heavily-templated Zoho-styled shell. LinaDesk's is a modern component-based UI with the same feature surface but a different structure. Copy the visual assets (logo, favicon, brand colors) and the text (welcome message, home-page announcements, category descriptions), and let a designer spend two days rebuilding the portal in LinaDesk's admin UI.
Notification templates are the same story. Extract each email template from SDP as HTML plus a variable list, then rebuild them in LinaDesk's template editor. LinaDesk's variable syntax is {{Ticket.Number}} style; SDP's is $Request.RequestID. Machine-translate the syntax; hand-review the copy.
Phase 8 — The four-week parallel run
Cutting over in a single weekend is a coin flip. Running SDP and LinaDesk in parallel for four weeks is not — it turns a coin flip into an engineering exercise.
Our recommended sequence:
- Week -4: LinaDesk deployed. Historical data imported. All L1 technicians have logins and have completed a 90-minute training session. Email routing still points at SDP.
- Week -3: Nightly re-import runs against SDP's delta API, keeping LinaDesk within 24 hours of SDP. Technicians are asked to spot-check ten new tickets a day in LinaDesk and file bugs. Portal remains dark.
- Week -2: Fifteen percent of inbound email is routed to LinaDesk. Technicians handle both queues. Reports are dual-generated and compared.
- Week -1: Fifty percent of inbound routed to LinaDesk. Portal beta open to a small set of pilot requesters. Any P0/P1 discrepancy blocks cut-over.
- Cut-over weekend: Final delta re-import. Email routing flipped to 100% LinaDesk. Portal opened to all requesters. SDP set to read-only; kept online for 90 days for audit.
The 90-day read-only period matters. Regulators (and internal audit) occasionally ask questions that require looking at how a ticket looked in the source system on a specific date. Deleting SDP the day after cut-over is a mistake we have seen twice, and both times it ended in an inconvenient legal-hold conversation.
Post-migration validation checklist
Before you sign off:
- Ticket counts match:
SDP.count(status=Closed, year=2024)equalsLinaDesk.count(status=Closed, CreatedAtUtc between 2024-01-01 and 2024-12-31)within ±0.1%. - Orphan requesters accounted for: every user in
orphans.csveither has a placeholder in LinaDesk or has been explicitly excluded, and their historical tickets show a preserved requester name in the ticket body. - SLA report parity: pull the previous quarter's SLA compliance report from SDP and from LinaDesk; the numbers should be within ±1%. Larger deltas indicate a calendar or pause-status misconfiguration.
- Attachment integrity: sample 200 random tickets across the last five years and verify every attachment opens.
- KB search: search for the five most-viewed knowledge articles in LinaDesk and confirm they surface in the top five results.
- Integrations: every re-pointed webhook, LDAP sync, and outbound API call has been observed firing successfully at least twice.
Common pitfalls
Features that exist in SDP but not in LinaDesk v1
The honest list. LinaDesk v1 does not ship:
- A project-management module. SDP's Projects submodule is used by roughly 15% of SDP customers; if you are one of them, this is a scope decision, not a workaround.
- An MSP multi-account tenancy layer. LinaDesk is single-tenant by design — each customer runs their own instance.
- A native mobile app. LinaDesk's web UI is mobile-responsive, but a native shell is on the v1.2 roadmap, not in v1.
If any of these are load-bearing for your operation, resolve it in discovery, not the week before cut-over.
Under-scoping custom-field migration
Every migration we have looked at had at least one custom field that was populated on 60% of historical tickets but on only 3% of the last year's tickets. Someone stopped using it years ago and nobody removed it. Migrate it anyway — orphaned data is still audit-visible data.
Trusting SDP's "date range" export UI
The SDP export UI silently caps rows at 5,000 in some builds and 10,000 in others, and there is no error — just a truncated CSV. Always use the API for anything above a few hundred rows.
Talk to us about your SDP migration
We have run this playbook end-to-end four times in the last eighteen months. If you are planning yours, we will walk you through the discovery template we use.
Contact the LinaDesk team