Copying or moving files around in SharePoint Online

Viewed 1556

I see so many people struggling to copy or moving files around in SharePoint online, that I decided to write a small demo console app to show how to do it. We will be using the CreateCopyJobs method, available on CSOM to copy a folder from one site collection to another. This method can be used to copy or move files between site collections or even on the same SC, betwen different libraries or folders inside a library. The method works exactly as the UI, when you try to copy or move something in a library.

1 - Create new .NET console app. We will be using PnP, so go to your project NuGet manager and add SharePointPnPCoreOnline

2 - add to the usings of your class the following:

using Microsoft.SharePoint.Client;
using Newtonsoft.Json;
using OfficeDevPnP.Core;

3 - Define the following class to receive the status of the job that we will be checking.

class CopyJobProgress
{
    public string Event;
    public string JobId;
    public string CorrelationId;
}

4 - Now add this sample main method:

static void Main(string[] args)
    {
        var siteUrl = "https://...-admin.sharepoint.com";
        var userName = "admin@...";
        var password = "....";

        AuthenticationManager authManager = new AuthenticationManager();

        using (var ctx = authManager.GetSharePointOnlineAuthenticatedContextTenant(siteUrl, userName, password))
        {
            var web = ctx.Web;
            ctx.Load(web);
            ctx.ExecuteQuery();

            string sourceFile = "https://....sharepoint.com/sites/<site>/<library>/<file or folder>";
            string destinationPath = "https://....sharepoint.com/sites/<site>/<destination library>";

            var createJobInfo = ctx.Site.CreateCopyJobs(new string[] { sourceFile }, destinationPath, 
                new CopyMigrationOptions() { IsMoveMode = false, IgnoreVersionHistory = true, 
                    AllowSchemaMismatch = true, NameConflictBehavior = MigrationNameConflictBehavior.Replace });

            ctx.ExecuteQueryRetry();

            Dictionary<string, CopyJobProgress> eventsFound = new Dictionary<string, CopyJobProgress>();
            bool jobEndFound = false;

            while (!jobEndFound)
            {
                var progress = ctx.Site.GetCopyJobProgress(createJobInfo[0]);
                ctx.ExecuteQuery();

                foreach (string log in progress.Value.Logs)
                {
                    CopyJobProgress progressRes = (CopyJobProgress)JsonConvert.DeserializeObject(log, typeof(CopyJobProgress));

                    if (!eventsFound.ContainsKey(progressRes.Event))
                    {
                        Console.WriteLine(DateTime.Now + " - " + progressRes.Event + " - CorrelationId: " + progressRes.CorrelationId);
                        eventsFound[progressRes.Event] = progressRes;
                    }

                    if (progressRes.Event == "JobEnd")
                    {
                        jobEndFound = true;
                    }
                }

                if (!jobEndFound)
                    System.Threading.Thread.Sleep(2000);
            }

            Console.WriteLine("Done!");
        }
    }
0 Answers
Related