Da man mit Export-SPWeb bzw. Import-SPWeb bzw. im GUI über granular Backup/Restore nur ganze Document Libraries kopieren kann hab ich mich auf die Suche gemacht und bin hierauf gestoßen. Da das dort aufgeführte “Programm” eher nicht so 1:1 zu verwenden war (und auch bei den Foldern beispielsweise Author/Timestamp nicht setzt) und ich die Geschichte mit Excel, Versionen und verschiedenen Modi etc. nicht benötigte habe ich es entsprechend umgeschrieben (mit Hilfe). Ohne wirklich Errorhandling und kaum Logging – aber es hat einwandfrei funktioniert (SharePoint ist offenbar relativ relaxed wenn man Dinge added die es schon gibt):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using Microsoft.SharePoint;

namespace Gallauner
{
   class SharepointListCopy
   {
      static void Main(string[] args)
      {
         string sSourceSite = "https://oldsite.domain.com";
         string sSourceWebName = "SomeWeb";
         string sSourceListName = "SomeList";
         string sSourceFolderName = "SomePath/MorePath/LastPath";
         string sDestSiteName = "https://newsite.domain.com";
         string sDestWebName = "SomeNewWeb/SubWeb";
         string sDestListName = "SomeNewList";
         string sDestFolderName = "";
         SPSite oSourceSite;
         SPList oSourceList;
         SPWeb oSourceWeb;
         SPListItemCollection oFolders;
         Microsoft.SharePoint.Administration.SPWebApplication oWebApp;

         // open source site/web/list
         oSourceSite = new SPSite(sSourceSite);
         oWebApp = oSourceSite.WebApplication;
         oWebApp.FormDigestSettings.Enabled = false;

         if (sSourceWebName == "")
            oSourceWeb = oSourceSite.RootWeb;
         else
            oSourceWeb = oSourceSite.OpenWeb(sSourceWebName);

         oSourceList = oSourceWeb.Lists[sSourceListName];
         if (oSourceList != null)
         {
            // search source folder
            oFolders = oSourceList.Folders;
            foreach (SPListItem oFolder in oFolders)
            {
               if (oFolder.Folder.Url == sSourceFolderName)
               {
                  // copy folder 
                  CopyFilesAndSubFolders(oLog, oFolder.Folder, oSourceWeb, 
                     sDestSiteName, sDestWebName, sDestListName, sDestFolderName);
               }
            }
         }
         oWebApp.FormDigestSettings.Enabled = true;
      }

      private static void CopyFilesAndSubFolders(Logfile oLog, SPFolder oFolder,
                                                 SPWeb oSourceWeb,string sDestSiteName,
                                                 string sDestWebName,string sDestListName,
                                                 string sDestFolderName)
      {
         SPSite oDestSite;
         SPWeb oDestWeb;
         SPList oDestList;
         SPFolder oDestFolder, oNewDestFolder;
         SPFile oFileCopy;
         SPUser oUser;

         // open site/web/list
         oDestSite = new SPSite(sDestSiteName);
         if (sDestWebName == "")
            oDestWeb = oDestSite.RootWeb;
         else
            oDestWeb = oDestSite.OpenWeb(sDestWebName);
         oDestList = oDestWeb.Lists[sDestListName];

         // find folder
         oDestFolder = null;
         if (sDestFolderName == "")
            oDestFolder = oDestList.RootFolder;
         else
         {
            foreach (SPListItem oTmpFolder in oDestList.Folders)
            {
               if (oTmpFolder.Folder.Url == sDestFolderName)
               {
                  oDestFolder = oTmpFolder.Folder;
                  break;
               }
            }
         }
         if (oDestFolder == null)
         {
            Console.WriteLine($"Cannot find destination folder '{sDestFolderName}'");
            return;
         }

         // copy files
         foreach (SPFile oFile in oFolder.Files)
         {
            Console.WriteLine($"FILE       {oFile.Name}");
            try
            {
               // add modifying user to destination web
               oUser=oDestWeb.EnsureUser(
                      (string)oFile.Properties["vti_modifiedby"]
                     );
            }
            catch (Exception)
            {
               // add failed, use me as modifying user
               oUser = oDestWeb.CurrentUser;
            }


            oFileCopy = oDestFolder.Files.Add(
                            $"{oDestWeb.Url}/{oDestFolder.Url}/{oFile.Name}", 
                            oFile.OpenBinaryStream(), 
                            oFile.Properties, 
                            oUser, 
                            oUser, 
                            (DateTime)oFile.Properties["vti_timelastmodified"],
                            (DateTime)oFile.Properties["vti_timelastmodified"],
                            oFile.CheckInComment, 
                            true);
         }

         // copy folders
         foreach (SPFolder oSubFolder in oFolder.SubFolders)
         {
            Console.WriteLine($"FOLDER {oSubFolder.Url}");

            try
            {
               // add modifying user to destination web
               oUser = oDestWeb.EnsureUser(
                        (string)oSubFolder.Properties["vti_modifiedby"]
                      );
            }
            catch (Exception)
            {
               // add failed, use me as modifying user
               oUser = oDestWeb.CurrentUser;
            }

            // first create on destination list
            oNewDestFolder = oDestFolder.SubFolders.Add(oSubFolder.Name);

            // set author/editor and timestamps
            SPListItem oTmp = oDestList.GetItemByUniqueId(oNewDestFolder.UniqueId);
            oTmp["Author"] = oUser;
            oTmp["Editor"] = oUser;
            oTmp["Created"] = oSubFolder.Properties["vti_nexttolasttimemodified"];
            oTmp["Modified"] = oSubFolder.Properties["vti_nexttolasttimemodified"];
            oTmp.Update();

            // call ourself recursively
            CopyFilesAndSubFolders(oLog, oSubFolder, oSourceWeb, 
                                   sDestSiteName, sDestWebName, 
                                   sDestListName, oNewDestFolder.Url);
         }

         // cleanup objects
         oDestWeb.Dispose();
         oDestSite.Dispose();
      }
   }
}

Die Reference Assembly bekommt man über das Nuget Package “Microsoft.SharePoint”, laufen lassen kann man das Ding dann allerdings nur auf einem SharePoint Server – mit Remote Debugger lässts sich dann aber bequem testen/debuggen.