Build a shared-drive migration helper
Move Northwind files between drives with structure intact — from My Drive to a Shared Drive.
Published Oct 8, 2025
Northwind’s project files have outgrown a single person’s My Drive. The problem with files owned by an individual is ownership: when that person leaves, the files go with them. A Shared Drive fixes that — files belong to the team — but Google offers no one-click “move this folder tree across” button, and dragging hundreds of nested files by hand is a long, error-prone afternoon.
This script does the move for you. Given a source folder and a target parent, it recreates the folder inside the target Shared Drive and walks the whole tree, copying every file and rebuilding every sub-folder in place. The result is a faithful copy of the structure, now owned by the team instead of a person.
What you’ll need
- The Drive API advanced service enabled. In the Apps Script editor, open
Services, add Drive API, and keep the default identifier
Drive. - The ID of the source folder you want to migrate (from a My Drive or another location).
- The ID of the target parent — a Shared Drive itself, or a folder inside one.
- Edit access to both the source and the target so the script can read one and write to the other.
The script
/**
* Migrates a folder tree into a target parent. Recreates the source
* folder inside the target, then copies every file and sub-folder.
*
* @param {string} sourceFolderId The folder to migrate.
* @param {string} targetParentId The parent (Shared Drive or folder) to copy into.
*/
function migrateFolder(sourceFolderId, targetParentId) {
const source = DriveApp.getFolderById(sourceFolderId);
// 1. Recreate the top-level folder inside the target.
const newFolder = createInTarget(source.getName(), targetParentId);
// 2. Walk the tree, copying files and rebuilding sub-folders.
copyContents(source, newFolder.id);
Logger.log('Migrated "' + source.getName() + '" into ' + targetParentId);
}
/**
* Creates a new folder with the given name inside a parent. Works for
* Shared Drive parents because supportsAllDrives is set.
*
* @param {string} name The new folder's name.
* @param {string} parentId The parent folder or Shared Drive ID.
* @return {Object} The created folder resource.
*/
function createInTarget(name, parentId) {
return Drive.Files.create(
{ name, mimeType: MimeType.FOLDER, parents: [parentId] },
null,
{ supportsAllDrives: true }
);
}
/**
* Copies every file from a source folder into a target folder, then
* recurses into each sub-folder, rebuilding the structure as it goes.
*
* @param {Folder} sourceFolder The folder to copy from.
* @param {string} targetFolderId The folder ID to copy into.
*/
function copyContents(sourceFolder, targetFolderId) {
// Copy every file at this level into the target folder.
const files = sourceFolder.getFiles();
while (files.hasNext()) {
const f = files.next();
Drive.Files.copy(
{ name: f.getName(), parents: [targetFolderId] },
f.getId(),
{ supportsAllDrives: true }
);
}
// For each sub-folder, recreate it in the target and recurse into it.
const subs = sourceFolder.getFolders();
while (subs.hasNext()) {
const sub = subs.next();
const sub2 = createInTarget(sub.getName(), targetFolderId);
copyContents(sub, sub2.id);
}
}
How it works
migrateFolderopens the source folder and callscreateInTargetto make a matching folder inside the target parent. This is the new root of the migrated tree.- It then calls
copyContents, passing the source folder and the ID of the freshly created target folder. createInTargetusesDrive.Files.createwithsupportsAllDrives: true— the flag that lets the call write into a Shared Drive, which the plainDriveAppmethods cannot reliably do.copyContentsfirst copies every file at the current level into the target folder, again withsupportsAllDrives: trueso copies land inside the Shared Drive.- It then loops over each sub-folder, recreates it in the target with
createInTarget, and calls itself recursively. This rebuilds the entire nested structure folder by folder.
Example run
Call migrateFolder with a source folder and a Shared Drive folder as the
target:
Source (My Drive) Target (Shared Drive)
└── Client projects/ └── Client projects/ ← recreated
├── proposal.pdf → ├── proposal.pdf ← copied
├── budget.xlsx → ├── budget.xlsx ← copied
└── Designs/ → └── Designs/ ← recreated
└── logo.png → └── logo.png ← copied
The structure on the right is a fresh copy: same folders, same files, now owned by the Shared Drive instead of an individual.
Run it
This is a one-off job, run by hand when a tree needs to move:
- In the Apps Script editor, write a small wrapper that calls
migrateFolderwith your two IDs, for examplemigrateFolder('1srcFolderId', '1targetParentId'). - Select that wrapper and click Run.
- Approve the authorisation prompt the first time.
- Check the target Shared Drive — the folder tree should be there in full.
Watch out for
- This copies, it does not move. The originals stay in the source, and the copies are owned by whoever ran the script — which, inside a Shared Drive, is the desired outcome. Delete the originals only once you have verified the copy.
- Copying loses version history, comments, and the original file IDs. Anything linking to a file by its old URL will need re-pointing.
- A large tree can blow the six-minute Apps Script execution limit. For thousands of files, migrate in batches or drive the recursion from a queue that survives across timed runs.
- Each
Drive.Files.copyandcreatecounts against your daily Drive API quota. A big migration can exhaust it. - Shared file permissions are not copied with the file. Re-share migrated files as needed, or rely on the Shared Drive’s own membership.
- Test on a small folder first. A recursive copy with a wrong target ID can scatter copies into the wrong place quickly.
Related
Archive a project folder when it's marked done
Zip and shelve completed Northwind work — keep active folders focused on in-flight projects.
Updated Dec 11, 2025
Build a version-snapshot system for key files
Keep dated copies of Northwind's critical Sheets before risky edits.
Updated Sep 22, 2025
Bulk-restore accidentally trashed files
Recover everything trashed in a date range — Northwind's emergency-undo button.
Updated Sep 14, 2025
Pre-create dated archive folders
Generate per-month folders ahead of time so nothing lands in `misc/`.
Updated Sep 2, 2025
Move stale files to cold storage
Archive Northwind Drive files untouched for a year into a `cold storage` folder.
Updated Aug 1, 2025