My organization is switching to a Google Business account, and everyone needs to transfer their Drive files to their new accounts. Drive will not allow transfer of ownershi
I know you would like a easy, programmatic way to do this, but it may be easiest to install Google Drive for Desktop and have them right-click, copy, paste.
The idea:
Just a thought.
I think I have solved the conceptual problem, though I am getting
We're sorry, a server error occurred. Please wait a bit and try again. (line 9, file "Code")
when I try to execute it.
Basically, I set it up to only try to copy one top-level folder at a time, and for each one of those it uses the recursive functions I had before. It should save continuation tokens for that first level of folders and any files in the root folder so it can pick up in the next execution where it left off. This way, the tokens are not involved in my recursive stack of functions.
function copyDrive() {
var originFolder = DriveApp.getFolderById(originFolderID);
var destination = DriveApp.getFolderById(destinationID);
var scriptProperties = PropertiesService.getScriptProperties();
var fileContinuationToken = scriptProperties.getProperty('FILE_CONTINUATION_TOKEN');
var fileIterator = fileContinuationToken == null ?
originFolder.getFiles() : DriveApp.continueFileIterator(fileContinuationToken);
var folderContinuationToken = scriptProperties.getProperty('FOLDER_CONTINUATION_TOKEN');
var folderIterator = folderContinuationToken == null ?
originFolder.getFolders() : DriveApp.continueFolderIterator(folderContinuationToken);
try {
var rootFileName;
while(fileIterator.hasNext()) {
var rootFile = fileIterator.next();
rootFileName = rootFile.getName();
rootFile.makeCopy(rootFileName, destination);
}
var folder = folderIterator.next();
var folderName = folder.getName();
var folderCopy = folder.makeCopy(folderName, destination);
copyFiles(folder, folderCopy);
} catch(err) {
Logger.log(err);
}
if(fileIterator.hasNext()) {
scriptProperties.setProperty('FILE_CONTINUATION_TOKEN', fileIterator.getContinuationToken());
} else {
scriptProperties.deleteProperty('FILE_CONTINUATION_TOKEN');
}
if(folderIterator.hasNext()) {
scriptProperties.setProperty('FOLDER_CONTINUATION_TOKEN', folderIterator.getContinuationToken());
} else {
scriptProperties.deleteProperty('FOLDER_CONTINUATION_TOKEN');
}
};
function copyFiles(passedFolder, targetFolder) {
var fileContents = passedFolder.getFiles();
var file;
var fileName;
while(fileContents.hasNext()) {
file = fileContents.next();
fileName = file.getName();
file.makeCopy(fileName, targetFolder);
}
copySubFolders(passedFolder, targetFolder);
};
function copySubFolders(passedFolder, targetFolder) {
var subFolderContents = passedFolder.getFolders();
var subFolder;
var subFolderName;
while(folderContents.hasNext()) {
subFolder = subFolderContents.next();
subFolderName = subFolder.getName();
var subFolderCopy = targetFolder.createFolder(folderName);
copyFiles(subFolder, subFolderCopy);
}
};
You're going to need to store an array of folder iterators and file iterators since each folder could have a nested array of folders. If you're reusing the same folder iterator as in the accepted solution, you won't be able to resume on more top level folders.
Take a look at my answer here for a template that you can use to recursively iterate over all the files in a drive with resume functionality built-in.