Reputation: 1090
I want to remove a person from the list of people who have access to files and folders.
I can do that using the code below but as I have a lot of files it takes long and I have to restart the process several times and manually change a variable (var count = 5600) several times in order to get the job done.
This can't be the right solution so I would like to know:
a) Is it possible to remove a user from ALL files (and folders) with a single call?
b) How can I remove a viewer from a bunch of files/folders fast(er)?
I know I could use a continuationtoken
to avoid changing the code between restarts but I haven't tried that.
function removeUser()
{
var userName = 'John Doe';
removeUserFromViewersAndEditors_(userName);
};
function removeUserFromViewersAndEditors_(userName)
{ // Remove a user from viewers and editors
// Currently maximum runtime will be exceeded. Using a continuationtoken and automatically starting batches it is possible
// to make it run a sequence of batches and perform its task.
// As this script will not be run often, a manual approach is preferred for now.
// Start with count = 0 and phase = 0
// After the program finishes change phase = 1 and start again
// The program will stop on execution time limit reached change count = ?? based on the log and start again
var count = 5600; // Update if maximum runtime exceeded
var phase = 1; // Update if maximum runtime exceeded
var user = findUser_(userName, phase, count);
var totalRemovedFolders = 0;
var totalRemovedFiles = 0;
if (user != null)
{
if (phase == 0)
{
var countFolders = 0;
var folders = DriveApp.getFolders();
while(folders.hasNext())
{
if (removeUserFromFolderOrFile_(folders.next(), user) == true) totalRemovedFolders++;
countFolders++;
}
Logger.log('testRemoveUser Folders : count= ' + countFolders + ' totalRemovedFolders= ' + totalRemovedFolders);
}
else if (phase == 1 )
{
var countFiles = count;
var files = DriveApp.getFiles();
while(count--) files.next(); // Skip a number of files
while(files.hasNext())
{
if (removeUserFromFolderOrFile_(files.next(), user) == true) totalRemovedFiles++;
countFiles++;
if ((100 * ((countFiles/100) | 0)) == countFiles)
{
Logger.log('phase= ' + phase + ' count= ' + countFiles + ' user= ' + userName + ((user == null) ? '' : ' found totalRemovedFiles= ' + totalRemovedFiles ));
}
}
Logger.log('testRemoveUser Files : count= ' + countFiles + ' totalRemoved= ' + totalRemovedFiles);
}
}
Logger.log('totalRemoved= ' + (totalRemovedFolders + totalRemovedFiles));
//////////////////// Internal functions removeUserFromViewersAndEditors_
function removeUserFromEvents_(userName)
{ // Must be executed BEFORE the user will be removed from memberNames (so : delete user from contacts AFTERWARDS !!)
var removed = 0;
var dateFrom = new Date();
var future = Date.now() + 2 * 365 * 24 * 60 * 60 * 1000 ; // 2 years from now (milliseconds)
var dateUntil = new Date(future)
var fileName = OPA_Agenda;
var cal = CalendarApp.getCalendarsByName(OPA_Calendar)[0];
var events = cal.getEvents(dateFrom, dateUntil); // All events within the timeframe
var numEvents = events.length;
var memberNames = getMemberNames_();
var memberEmails = getMemberEmails_();
var numMembers = memberNames.length;
for (var i=0; i<numMembers; i++)
{
if (userName == memberNames[i])
{ // found
var email = memberEmails[i];
for (var j=0; j<numEvents; j++)
{
var event = events[j];
var guests = event.getGuestList();
var numGuests = guests.length;
for (var k=0; k<numGuests; k++)
{
if (email == guests[k].getEmail())
{
event.removeGuest(email); // Removed from this event
Logger.log(userName + ' removed from event : ' + event.getTitle() + ' at ' + event.getStartTime());
removed++;
break;
}
}
}
break;
}
}
Logger.log(userName + ' removed from ' + removed + ' events');
return removed;
}
function removeUserFromFolderOrFile_(fileOrFolder, user)
{ // Remove <user> as editor or viewer from a file or a folder
var removed = false;
var array = [];
var userName = user.getName();
for (var i=0; i<2; i++)
{
if (i == 0) array = fileOrFolder.getEditors();
else if (i == 1) array = fileOrFolder.getViewers();
var size = array.length;
while(size--)
{
if (userName == array[size].getName())
{
if (i == 0) fileOrFolder.removeEditor(array[size]);
else if (i == 1) fileOrFolder.removeViewer(array[size]);
Logger.log('User ' + userName + ' removed from ' + fileOrFolder.getName());
removed = true;
break;
}
}
}
return removed;
}
function findUser_(name, phase, count)
{
var iterator = null;
var user = null;
for (var i=0; i<2; i++)
{
Logger.log('findUser phase ' + i);
if (i == 0)
{
iterator = DriveApp.getFolders();
if (phase == 0)
{ // Skip <count> folders
for (var j=0; j<count; j++) var object = iterator.next();
}
else iterator = null;
}
else if (i == 1)
{
iterator = DriveApp.getFiles();
if (phase == 1)
{ // Skip <count> files
for (var j=0; j<count; j++) var object = iterator.next();
}
else
{ // Just finished checking folders
count = 0;
phase = 1;
}
}
if (iterator != null)
{
while (iterator.hasNext() && (user == null))
{
var object = iterator.next();
var array = [];
for (var j=0; j<2; j++)
{
if (j == 0) array = object.getEditors();
else if (j == 1) array = object.getViewers();
var size = array.length;
while(size--)
{
if ((name == array[size].getName()) || (name == array[size].getEmail()))
{ // Found
user = array[size];
break;
}
}
}
count++;
if ((100 * ((count/100) | 0)) == count)
{
Logger.log('phase= ' + phase + ' count= ' + count + ' user= ' + name + ((user == null) ? '' : ' found'));
}
}
}
}
Logger.log('findUser(' + name + ') ' + ((user == null) ? 'failed' : 'succeeded'));
return user;
}
//////// End internal functions removeUserFromViewersAndEditors_
}
Upvotes: 0
Views: 1045
Reputation: 13469
I don't see any example for your use case. You may refer with this related product forum but using GAM command like:
gam all users show filelist query "'[email protected]' in writers or '[email protected]' in readers" id | gam csv - gam user ~Owner delete drivefileacl ~id [email protected]
The first command will generate a CSV list of all files shared with the vendor email address (read or write access) for all users in your domain. If you have lots of users in your domain it's going to take awhile to generate this list. The 2nd command after the | pipe reads in this CSV list and performs the delete ACL operation for each and every file that is shared with the vendor.
You can also check this thread.
Upvotes: 1