0

I want to reset all Files & folders permissions to "restricted". on the entire drive.

Permissions on google drive don't cascade so removing them from parent folder won't remove them on Sub-folders & files. And I have an very large number of files and folders.

I found and outdated post with a script but the "Uiapp" function is deprecated (and someone in comment said something about it could remove some files so not really what I'm looking for)

This is the outdated post for something similar (Not working anymore) : https://webapps.stackexchange.com/questions/37592/how-do-i-reset-permissions-for-google-drive-documents-in-all-subfolders

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Mk1
  • 77
  • 1
  • 11
  • Can I ask you about the approximate number of files and folders you want to change the permissions to "restricted"? And in your situation, the target is all files and folders under the root folder? Or, the target is all files and folders under the specific folder? – Tanaike Oct 14 '21 at 08:43
  • All files and folders under root folder. i'd say around 60k files and 15k folders – Mk1 Oct 14 '21 at 09:05
  • Thank you for replying. I have 4 questions. 1. About `"restricted"` you expect, in this case, when a file is shared with other users, how will you do? 2. When the owner of the file is not you, what will you do? 3. In your situation, how about the shared Drive? 4. In your tag, `google-apps-script` is included. In your situation, Google Apps Script is used? If it's so, can you provide your current script? – Tanaike Oct 14 '21 at 10:49
  • 1- `Restricted` as in "all drive is private", nothing is shared, files and folders can only be seen by the drive owner (files owner). 2- I'm the owner of every file on my drive 3- I don't care about shared drive 4- I used `google-apps-script` because from previous threads i've seen, that how people do it. There is a link in my question containing an old thread with a deprecated function. I'm also unsure if its exactly what is needed in my case. Old script here : https://webapps.stackexchange.com/questions/37592/how-do-i-reset-permissions-for-google-drive-documents-in-all-subfolders – Mk1 Oct 14 '21 at 12:13
  • Thank you for replying. Now I noticed that an answer has already been posted. In this case, I would like to respect the existing answer. It will resolve your issue. – Tanaike Oct 14 '21 at 23:40

1 Answers1

4

Answer:

You can use the Drive API to retrieve all files, then loop through them setting the permissions to PRIVATE.

More Information:

The trickiest part here is the number of files you have will undoubtedly mean that the script execution time will far exceed the Apps Script limits. You can however get around this by storing all file IDs initially and then looping through them, continuing where you left off on last execution.

Code:

As the Drive API is faster than the in-built DriveApp, I'll be using this in my example. Make sure to enable the Drive Advanced Service before running.

function getAllFileIds() {
  const fileIds = []
  let files = Drive.Files.list({
    pageSize: 1000
  })

  while (files.nextPageToken) {
    console.log(files.nextPageToken)
    fileIds.push(...files.items.map(x => x.id))
    files = Drive.Files.list({
      pageSize: 1000,
      pageToken: files.nextPageToken
    })
  }
  fileIds.push(...files.items.map(x => x.id))

  const ss = SpreadsheetApp.create("Files List")
  const sheet = ss.getSheetByName("Sheet1")
  sheet.getRange(1, 1, fileIds.length, 1).setValues(fileIds.map(x => [x]))
  
  PropertiesService.getScriptProperties().setProperty("sheet", ss.getId())
}

function changePermissions() {
  const props = PropertiesService.getScriptProperties()
  const sheet = SpreadsheetApp.openById(props.getProperty("sheet")).getSheetByName("Files List")

  let ids

  const curr = parseInt(props.getProperty("index"))
  if (curr) {
    ids = sheet.getRange(curr, 1, sheet.getLastRow() - curr, 1).getValues().flat(2)
  }
  else {
    ids = sheet.getDataRange().getValues().flat(2)
  }

  ids.forEach(function(id, index) {
    try {
      console.log(id)
      DriveApp.getFileById(id).setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.VIEW)
    }
    catch(e) {
      console.info(e)
    }
    props.setProperty("index", index + 1)
  })
}

The idea is thus:

  • Run the function getAllFileIds(). This will:
  • Use the Drive API to retrieve up to 1000 files at a time and add all their IDs to an array.
  • Create a Spreadsheet to save all the IDs to.
  • Save the Spreadsheet ID to the script's properties for later access.

I opted to log each nextPageToken so you can see it runs - I have ~16,800 files and folders in my Drive and this function took a minute or so to run.

Then, you can run the function changePermissions(). This will:

  • Checks the script's properties for the ID of the spreadsheet and an index of how many rows have been completed
  • Opens the spreadsheet
  • If there is a saved index value, then the script starts from where it last left off
  • If there is no saved index value, the script starts from the beginning of the list
  • Loops through each file by ID and sets the Access to PRIVATE.
  • Each time a permission is changed, the new index gets saved to the script properties.

You will have to run this multiple times. I suggest creating a time based trigger so that the function runs multiple times without the need to manually re-run. You can find the instructions for this in this answer.

NB: Apps Script execution time limit is 6 minutes for Gmail accounts and 30 minutes for Business/Enterprise. Please bear this in mind when setting up an installable trigger so that individual script executions do not overlap.

References:

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Rafa Guillermo
  • 14,474
  • 3
  • 18
  • 54