Revert all files in a Google Drive directory to old version after ransomware attack

339 Views Asked by At

After a crypto virus attack all files on my PC and my Google Drive were encrypted. Thanks to Google Drive (I'm a Google Workspace user) is it possible to restore a previous version of each file, unfortunately Google Drive don't have a feature to do it massivly. So after some research I found a good answer to my problem here: Revert all files in a Google Drive directory to old version

I had to figure out some stuff before to be able to use it, so I'm gonna share all the steps I've done here:

  1. Add Google Apps Script to your Google account: https://www.google.com/script/start/
  2. Create a new project and rename it “File Recovery After Attack”.
  3. Add the Drive API Service (click on +)
  4. Enter the code below *****.
  5. Enter the root folder ID by copying it from the Google Drive URL (for example for the URL “https://drive.google.com/drive/folders/WC17rBbVhhn2v9qUssUoY” the ID is "WC17rBbVhhn2v9qUssUoY").
  6. Save the script.
  7. Run the script.
  8. Provide the necessary permissions the first time you run the script.

This is the *****CODE I used.

/** A function that delete all version of files in folder and subfolders that were made at the day of the virus attack and afterwards*/
function fixAllFilesInFolder(){ 
  var sh = SpreadsheetApp.getActiveSheet();
  var folderId = '1TYU3R4y6VKNJC_iAsRinK0s4YfVsXdfX' // Change the folder ID  here 
  var folder = DriveApp.getFolderById(folderId); 
  handleFolder(folder, 0)   
}



/** A recursive function - delete all 'bad' versions of files in folder and calls itself with each of the subfolders to do the same*/
function handleFolder(folder, treeRank){
  Logger.log(String(treeRank) + ': ' + folder.getName());
  fixFolderFiles(folder)
  var subFolders = folder.getFolders(); 
  while (subFolders.hasNext()){
    subFolder = subFolders.next();
    handleFolder(subFolder, treeRank + 1)
  }

}

/** Delete all 'bad' versions of files in folder*/
function fixFolderFiles(folder){
  var files = folder.getFiles(); 
  while (files.hasNext()){
    file = files.next();
    deleteRevisions(file)
  }
}

  /** Delete 'bad' version of a file*/
function deleteRevisions(file) {
  Logger.log(file);
  var fileId = file.getId();
  var revisions = Drive.Revisions.list(fileId);
  var virusDate = new Date("2023-09-28"); /** Change the date here, in "YYYY-MM-DD" format*/
    if (revisions.items && revisions.items.length > 1) {
    for (var i = 0; i < revisions.items.length; i++) {
      if (i > 0) { // rev[0] (v1) is original file version
        var revision = revisions.items[i];
        var revDate = new Date(revision.modifiedDate);
        if (revDate.getTime() > virusDate.getTime()) {
          Logger.log("Gonna delete " + file + " v." + i + "-" + revDate.toISOString());
          //return Drive.Revisions.remove(fileId, revision.id);
          Drive.Revisions.remove(fileId, revision.id);
          fixFileNameAndModifiedDate(file);

        }
      }
    }
  } else {

    fixFileNameAndModifiedDate(file);

  }
}


/** Fix 'correct' File Name & Last modified Date  */
function fixFileNameAndModifiedDate(file) {

  var fileId = file.getId();
  var revisions = Drive.Revisions.list(fileId);
  var lastFileVNr = revisions.items.length - 1; // Last File Version Number
  var lastFileVIt = revisions.items[lastFileVNr];  // Last File Version Item
  var lastFileVDt = new Date(lastFileVIt.modifiedDate); //Last File Version Date
  var lastFileVNm = lastFileVIt.originalFilename; //Last File Version Name
  var currFileMDt = file.getLastUpdated(); // Current File Modified Date
  var currFileMNm = file.getName(); // Current File Name .getName()

  // Different Modified Dates
  if (lastFileVDt.getTime() !== currFileMDt.getTime() && lastFileVNm !== currFileMNm) {

    Logger.log("Gonna change modif date: " + lastFileVDt.toISOString())

    Drive.Files.patch({ modifiedDate: lastFileVDt.toISOString() },
      fileId,
      { modifiedDateBehavior: "fromBody", supportsAllDrives: true });

  }

  // Different File Name
  if (lastFileVNm !== currFileMNm) {

    Logger.log("Gonna change file name: " + lastFileVNm)

    Drive.Files.patch({ title: lastFileVNm },
      fileId,
      { supportsAllDrives: true });

  }

  return

}

But my drive is pretty big e busy, with a super complex folder tree... so, even if, I'm trying to change manually the main folder, the process is taking too long because of the "Script runtime execution time limit" which is, for Google Workspace user, of 30 minutes.

I can imagine the solution could be to save the current step before the timeout on an external file and then restart from there, but I don't know how to do it... Can anyone help me?

0

There are 0 best solutions below