SharePoint: How do I upload a file structure to a document library?

My current project uses a custom 'style library' document library. The deployment process needed to replicate the files and file structure from the disk in the target library.

I used CSOM and Powershell to solve the problem.

I created a 'Common' dll that contains the methods I needed:
1. CreateFolder (to create a folder structure)
2. UploadFile (to load the file).

    public static class FileHelper
    {
        public static Folder CreateFolder(Web web, string listTitle, string fullFolderPath)
        {
            if (string.IsNullOrEmpty(fullFolderPath))
                throw new ArgumentNullException("fullFolderPath");
            var list = web.Lists.GetByTitle(listTitle);
            return CreateFolderInternal(web, list.RootFolder, fullFolderPath);
        }

        private static Folder CreateFolderInternal(Web web, Folder parentFolder, string fullFolderPath)
        {
            var folderUrls = fullFolderPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            string folderUrl = folderUrls[0];
            var curFolder = parentFolder.Folders.Add(folderUrl);
            web.Context.Load(curFolder);
            web.Context.ExecuteQuery();

            if (folderUrls.Length > 1)
            {
                var folderPath = string.Join("/", folderUrls, 1, folderUrls.Length - 1);
                return CreateFolderInternal(web, curFolder, folderPath);
            }
            return curFolder;
        }

        public static void UploadFile(string siteUrl, string sourceFileFullLocation, string targetListTitle, string targetLocation)
        {
            UploadFile(siteUrl, sourceFileFullLocation, targetListTitle, targetLocation, new Dictionary<string, string>());
        }

        public static void UploadFile(string siteUrl, string sourceFileFullLocation, string targetListTitle, string targetLocation, Dictionary<string, string> items)
        {
            using (var context = new ClientContext(siteUrl))
            {
                ConnectionHelper.SetCredential(context);

                var web = context.Web;
                context.Load(web);
                context.Load(web.CurrentUser);
                context.Load(web.Lists);
                context.ExecuteQuery();

                var newFile = new FileCreationInformation()
                {
                    Overwrite = true,
                    Content = System.IO.File.ReadAllBytes(sourceFileFullLocation),
                    //Url = targetLocation,
                    Url = Path.Combine(targetLocation, Path.GetFileName(sourceFileFullLocation))
                };

                var targetFolder = context.Web.GetFolderByServerRelativeUrl(targetLocation);
                context.Load(targetFolder);
                context.ExecuteQuery();

                Microsoft.SharePoint.Client.File uploadFile = targetFolder.Files.Add(newFile);

                if (items != null)
                {
                    foreach (KeyValuePair<string, string> item in items)
                    {
                        uploadFile.ListItemAllFields[item.Key] = item.Value;
                    }
                }

                uploadFile.ListItemAllFields.Update();

                context.Load(uploadFile);
                context.ExecuteQuery();
            }
        }

Once the code was compiled into a dll, I instantiated them in my powershell code:

Function LoadDll($location)
{
$bytesCommon = [System.IO.File]::ReadAllBytes("$location")
$loadResultCommon = [System.Reflection.Assembly]::Load($bytesCommon)
}

The last part is to recursively loop through the folder structure and create the items in the target location

Function UploadFiles($siteUrl, $sourceFolder, $siteRelativeUrl)
{
$listName = "MyStyleLibraryList"
CreateLibrary $siteUrl $listName

Get-ChildItem $sourceFolder -Filter *.* -Recurse | 
Foreach-Object{
$name = $_.Name
$folder = $_.FullName.Replace($sourceFolder, "").Replace("\", "/")
$folder = $folder.Substring(1, $folder.Length - 1)
if ($_.PSIsContainer -eq $true)
{
Write-Host "Creating folder $folder"
CreateFolder $siteUrl $listName $folder
}
else
$folderWithFileName = $_.FullName.Replace("$sourceFolder", "")
$folder = $folder.Replace($_.Name, "")
UploadFile $siteUrl  $_.FullName $listName "$listName/$folder" $folderWithFileName
}
}
}

Function CreateFolder($siteUrl, $listName, $folderName)
{
[MyHelperSolution.FileHelper]::CreateFolder($siteUrl, $listName, $folderName)
}

Function UploadFile($siteUrl, $sourceFolder, $listName, $siteRelativeUrl, $folderWithFile)
{
[MyHelperSoltuion.FileHelper]::UploadFile($siteUrl, $sourceFolder, $listName, $siteRelativeUrl)
}

Comments

Popular posts from this blog

SharePoint 2013: Error updating managed account credentials

How can I call a JIRA api through Powershell?