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.

is a software solution company that was established in 2016. Our quality services begin with experience and end with dedication. Our directors have more than 15 years of IT experience to handle various projects successfully. Our dedicated teams are available to help our clients streamline their business processes, enhance their customer support, automate their day-to-day tasks, and provide software solutions tailored to their specific needs. We are experts in Dynamics 365 and Power Platform services, whether you need Dynamics 365 implementation, customization, integration, data migration, training, or ongoing support.

Share This Story, Choose Your Platform!

Dynamics 365 Document ManagementSimplifying CRM Document Management in Dynamics 365
Dynamics 365 Document ManagementExtending Dynamics 365 Document Generation: Building a Custom Document Management & Versioning Framework (Part 1)