Skip to content
●
Microsoft-Focused Solutions & Delivery
|
Dynamics 365 · Business Central · Power Platform
|
Global Delivery · UAE Presence
Core Microsoft Platforms

Sales, Customer Service, Project Operations

ERP & CRM Integration, APIs & Data Workflows

Power Apps, Automate, BI, Pages & Dataverse

Specialist Services

APIs, Azure Logic Apps, Webhooks & SQL

8-Step Controlled Validation & Relational Mapping

Copilot Studio, Governed Pilots & Agents

Health Checks, Workflow Fixes & Rescues

SkySoft Standalone Software
InspectionsTrack ↗

Digital inspection and reporting software for industrial operations.

SkySoft Compliance ↗

Digital QSE and compliance workflows for construction teams.

Confidential delivery capacity behind your partner brand

Senior specialists for project teams and ongoing backlogs

SkySoft Insights

Bulk File Download from SharePoint using a Custom Button in Dynamics 365 (Dataverse)

Bulk File Download from SharePoint in Dynamics 365

In many Dynamics 365 / Dataverse projects, users store documents in SharePoint document locations and later need a simple, user-friendly way to download one or multiple files directly from the CRM UI.

Out of the box, Dynamics does not provide an elegant solution to: – Select multiple records – Click a custom button – Download the related SharePoint files in one go

This blog explains a real-world production-ready solution using:

  • A custom ribbon button/command bar button
  • JavaScript (Web Resource)
  • A Custom Action + Plugin
  • Microsoft Graph API to fetch files from SharePoint

High-Level Architecture

Business Requirement

  • User selects one or multiple records (files)
  • Clicks Download Files button
  • System downloads files stored in SharePoint
  • No Power Automate
  • No external tools
  • Works directly inside the browser

Step 1: Custom Button (Command Bar)

A custom button is added to the grid or subgrid using: – Ribbon Workbench or – Modern Command Designer

The button passes the selected record IDs to JavaScript.

Bulk File Download from SharePoint in Dynamics 365

Step 2: JavaScript – Handling the Button Click

The JavaScript web resource performs the following tasks:

  • Reads selected record IDs
  • Shows a progress indicator
  • Calls a Dataverse Custom Action for each record
  • Receives SharePoint download URLs
  • Triggers browser downloads

Key JavaScript Function

async function downloadItem(selectedControlItemIds) {
    var Xrm = window.parent.Xrm;
    var recordId = Xrm.Page.data.entity.getId()

    const total = selectedControlItemIds.length;
    for (const [index, itemId] of selectedControlItemIds.entries()) {
        let current = index + 1;
        Xrm.Utility.showProgressIndicator(`Downloading file ${current}/${total}`);

        // Call Custom Action
        let downloadUrls = await callDownloadAction(itemId, recordId);

        if (downloadUrls) {
            if (Array.isArray(downloadUrls)) {
                for (const url of downloadUrls) {
                    triggerDownload(url);
                }
            } else {
                triggerDownload(downloadUrls);
            }
        }

        if (current === total) {
            Xrm.Utility.closeProgressIndicator();
        }
    }
}

Download Helper

function triggerDownload(url) {
    var anchor = document.createElement(“a”);
    anchor.href = url;
    anchor.download = “”;
    document.body.appendChild(anchor);
    anchor.click();
    document.body.removeChild(anchor);
}

Calling the Dataverse Custom Action

function callDownloadAction(itemId, recordId) {
    return new Promise((resolve, reject) => {
        var parameters = {
            FolderName: recordId,
            RecordID: itemId
        };

        var req = new XMLHttpRequest();
        var apiUrl = Xrm.Utility.getGlobalContext().getClientUrl()
            + “/api/data/v9.2/omac_DownloadFileFormSharpoint”;

        req.open(“POST”, apiUrl, true);
        req.setRequestHeader(“Content-Type”, “application/json; charset=utf-8”);
        req.setRequestHeader(“Accept”, “application/json”);

        req.onreadystatechange = function () {
            if (req.readyState === 4) {
                if (req.status === 200 || req.status === 204) {
                    var result = JSON.parse(req.responseText);
                    resolve(result[“DownloadablURL”]);
                } else {
                    reject(req.responseText);
                }
            }
        };

        req.send(JSON.stringify(parameters));
    });
}

Step 3: Custom Action (Dataverse)

A Custom Action is created with:

Input Parameters

  • FolderName (string) → Parent record GUID
  • RecordID (string) → Selected file record ID

Output Parameters

  • DownloadablURL (string)
  • FileName (string)

The action is executed by JavaScript and handled by a plugin.

Step 4: Plugin – Fetching Files from SharePoint

The plugin performs the heavy lifting:

  • Resolves SharePoint document location
  • Uses Microsoft Graph API
  • Finds the correct file
  • Generates a secure download URL

Plugin Core Logic (Simplified)

string FolderName = (string)context.InputParameters[“FolderName”];
string RecordID = (string)context.InputParameters[“RecordID”];

FolderName = CRMServicesObj.GetDocumentLocationRelativeUrl(service, FolderName);

Get SharePoint Folder via Graph API

var driveResponseJson = GraphApiService
    .GetDriveItemAsync(FolderName, tenant, tracingService)
    .GetAwaiter().GetResult();

Fetch Files & Generate Download URL

var (url, fileName) = GraphApiService
    .GetMicrosoftGraphDownloadUrl(driveResponseJson, RecordID);

context.OutputParameters[“DownloadablURL”] = url;
context.OutputParameters[“FileName”] = fileName;

Why Microsoft Graph API?

  • Secure
  • Modern authentication (Azure AD)
  • Works with SharePoint Online
  • No legacy SharePoint SOAP APIs

Benefits of This Approach

✔ Works entirely inside Dynamics 365

✔ Supports single & multiple file downloads

✔ No Power Automate licensing cost

✔ Clean UI experience

✔ Browser-safe sequential downloads

✔ Reusable across entities

Final Thoughts

This pattern is extremely useful when: – Files are stored in SharePoint – Users want a one-click download experience – Performance and UX matter

With a small amount of JavaScript and a well-designed plugin, you can deliver a powerful enterprise-grade solution fully integrated with Dynamics 365.

Read more : dynamics 365 document management made simple

FAQ’s

Can users download multiple SharePoint files at once from Dynamics 365?

Yes. This solution allows users to select one or multiple records and download all related SharePoint files in a single click directly from the Dynamics 365 UI.

Does this solution require Power Automate or third-party tools?

No. The entire implementation works natively within Dynamics 365 using JavaScript, a Custom Action, a plugin, and Microsoft Graph API without Power Automate or external tools.

Is Microsoft Graph API secure for downloading SharePoint files?

Yes. Microsoft Graph uses modern Azure AD authentication and provides secure, permission-based access to SharePoint Online files.

Can this approach be reused for other entities or file types?

Absolutely. The solution is reusable across different entities and supports both single and multiple file downloads stored in SharePoint.