Skip to main content

Tool: Vollständiges Audit aller Google Drive Freigaben

1. Übersicht & Funktion

Dieses Tool dient der Sicherheitsüberprüfung des Google Drive Accounts. Es erstellt eine vollständige Inventur aller Dateien, die nicht privat sind.

Das Skript erkennt:

  • Öffentliche Links: Dateien, die für jeden im Internet sichtbar sind.
  • Personen-Zugriff: Dateien, die gezielt mit externen E-Mail-Adressen geteilt wurden.
  • Ordner-Struktur: Die Hierarchie bleibt erhalten (welche Datei liegt in welchem Ordner).

Das Ergebnis wird automatisch in eine neue Google Tabelle exportiert.


2. Anleitung für Einsteiger (Schritt-für-Schritt)

Auch ohne Programmierkenntnisse können Sie dieses Tool in wenigen Minuten einrichten.

Schritt A: Das Skript erstellen

  1. Öffnen Sie Ihr Google Drive.
  2. Klicken Sie oben links auf + Neu > Mehr > Google Apps Script.
  3. Es öffnet sich ein neuer Tab mit einem Code-Editor.
  4. Geben Sie dem Projekt oben links einen Namen (z. B. Sicherheits-Check).

Schritt B: Die "Drive API" aktivieren (WICHTIG!)

Damit das Skript schnell tausende Dateien scannen darf, muss ein spezieller Dienst aktiviert werden.

  1. Schauen Sie im Editor auf die linke Leiste.
  2. Klicken Sie neben dem Punkt „Dienste“ (Services) auf das + Zeichen.
  3. Scrollen Sie in der Liste zu Drive API und wählen Sie es aus.
  4. Achtung: Stellen Sie sicher, dass im Dropdown-Menü unten die Version v3 ausgewählt ist.
  5. Klicken Sie auf Hinzufügen.
    • Unter "Dienste" erscheint nun "Drive".

Schritt C: Code einfügen

  1. Löschen Sie im Editor den kurzen Code, der dort bereits steht (function myFunction...).
  2. Kopieren Sie den Code aus dem untenstehenden Abschnitt "Das Skript".
  3. Fügen Sie ihn in den Editor ein.
  4. Klicken Sie oben auf das Disketten-Symbol 💾 (Speichern).

Schritt D: Ausführen & Genehmigen

  1. Stellen Sie sicher, dass oben in der Leiste die Funktion generateFullSharingReport ausgewählt ist.
  2. Klicken Sie auf ▷ Ausführen.
  3. Nur beim ersten Mal: Google fragt nach Berechtigungen.
    • Klicken Sie auf Berechtigungen überprüfen.
    • Wählen Sie Ihr Google-Konto.
    • Es erscheint oft eine Warnung ("Google hasn’t verified this app"). Das ist normal, da Sie das Skript selbst erstellt haben.
    • Klicken Sie links unten auf Erweitert (Advanced).
    • Klicken Sie ganz unten auf den Link „Zu ... (Name des Skripts) gehen (unsicher)“.
    • Klicken Sie auf Zulassen (Allow).

Schritt E: Ergebnis prüfen

Das Skript läuft nun (unten sehen Sie ein gelbes Protokoll). Sobald dort „Fertig!“ steht, finden Sie direkt daneben den Link zur Google Tabelle mit Ihren Ergebnissen.


3. Das Skript

/**
 * SKRIPT: Audit aller Google Drive Freigaben (Personen & Links)
 * VERSION: 4.0 (Full Audit & Email-List)
 * * ZWECK:
 * Listet JEDE Datei auf, die nicht rein privat ist.
 * Zeigt Freigabestatus und konkrete E-Mail-Adressen an.
 *
 * VORAUSSETZUNG:
 * Dienst "Drive API" (Version 3) muss aktiviert sein.
 */

function generateFullSharingReport() {
  
  // --- 1. SETUP ---
  // Erstellt die Zieltabelle mit aktuellem Zeitstempel
  var timestamp = new Date().toLocaleString();
  var spreadsheet = SpreadsheetApp.create("Sicherheitsbericht: Alle Freigaben (" + timestamp + ")");
  var sheet = spreadsheet.getActiveSheet();
  
  Logger.log("Starte vollständigen Scan...");

  // --- 2. DATEN SAMMELN ---
  var allItemsMap = {}; 
  var rootItems = []; 
  
  var pageToken;
  var count = 0;
  
  do {
    // API v3 Abfrage: Holt ID, Name, Link, Eltern und detaillierte Berechtigungen
    var result = Drive.Files.list({
      q: "'me' in owners and trashed = false", 
      pageSize: 1000, 
      pageToken: pageToken,
      fields: "nextPageToken, files(id, name, mimeType, webViewLink, parents, permissions(type, role, emailAddress, allowFileDiscovery))" 
    });

    var files = result.files;
    
    if (files && files.length > 0) {
      for (var i = 0; i < files.length; i++) {
        var file = files[i];
        
        // Berechtigungen analysieren
        var analysis = analyzePermissions(file.permissions);
        
        // Wenn die Datei NICHT privat ist (also irgendeine Freigabe hat), nehmen wir sie auf
        if (analysis.isShared) {
          file.children = []; 
          file.analysis = analysis; 
          allItemsMap[file.id] = file;
          count++;
        }
      }
    }
    pageToken = result.nextPageToken; 
  } while (pageToken);

  Logger.log(count + " geteilte Elemente gefunden. Baue Struktur...");

  // --- 3. HIERARCHIE-STRUKTUR BAUEN ---
  // Ordnet Dateien ihren Eltern-Ordnern zu, um einen Baum zu erstellen
  for (var id in allItemsMap) {
    var item = allItemsMap[id];
    var parentId = (item.parents && item.parents.length > 0) ? item.parents[0] : null;
    
    if (parentId && allItemsMap[parentId]) {
      allItemsMap[parentId].children.push(item);
    } else {
      rootItems.push(item);
    }
  }

  // --- 4. AUSGABE GENERIEREN (Rekursiv) ---
  var outputRows = [];
  outputRows.push(["Dateiname (Struktur)", "Typ", "Link", "Freigabe-Status", "Berechtigte Personen"]); 

  function processNode(node, depth) {
    // Einrückung für Baumansicht berechnen
    var indent = "";
    for (var k=0; k<depth; k++) indent += "   "; 
    var visualName = indent + (depth > 0 ? "└─ " : "") + node.name;
    
    var typeLabel = (node.mimeType === 'application/vnd.google-apps.folder') ? "Ordner" : "Datei";
    
    var status = node.analysis.statusLabel;
    var users = node.analysis.userList;

    outputRows.push([visualName, typeLabel, node.webViewLink, status, users]);

    // Kinder sortieren (Ordner zuerst, dann alphabetisch)
    if (node.children.length > 0) {
      node.children.sort(function(a, b) {
        var aIsFolder = (a.mimeType === 'application/vnd.google-apps.folder');
        var bIsFolder = (b.mimeType === 'application/vnd.google-apps.folder');
        if (aIsFolder && !bIsFolder) return -1;
        if (!aIsFolder && bIsFolder) return 1;
        return a.name.localeCompare(b.name);
      });

      for (var j=0; j<node.children.length; j++) {
        processNode(node.children[j], depth + 1);
      }
    }
  }

  // Root-Elemente sortieren und Prozess starten
  rootItems.sort(function(a, b) {
     var aIsFolder = (a.mimeType === 'application/vnd.google-apps.folder');
     var bIsFolder = (b.mimeType === 'application/vnd.google-apps.folder');
     if (aIsFolder && !bIsFolder) return -1;
     if (!aIsFolder && bIsFolder) return 1;
     return a.name.localeCompare(b.name);
  });

  for (var i=0; i<rootItems.length; i++) {
    processNode(rootItems[i], 0);
  }

  // --- 5. IN TABELLE SCHREIBEN ---
  if (outputRows.length > 1) {
    sheet.getRange(1, 1, outputRows.length, 5).setValues(outputRows);
    sheet.getRange("A1:E1").setFontWeight("bold");
    sheet.setFrozenRows(1); // Fixiert die Kopfzeile
    sheet.setColumnWidth(1, 400); // Verbreitert die Namensspalte
    sheet.setColumnWidth(5, 300); // Verbreitert die E-Mail Spalte
  }

  Logger.log("Fertig! Bericht: " + spreadsheet.getUrl());
}

/**
 * HILFSFUNKTION: Analysiert Berechtigungen einer Datei
 * Priorisiert öffentliche Links über Personen-Freigaben
 */
function analyzePermissions(perms) {
  var isShared = false;
  var statusLabel = "Privat";
  var userEmails = [];

  if (perms) {
    for (var i = 0; i < perms.length; i++) {
      var p = perms[i];
      if (p.role === 'owner') continue; // Eigentümer ignorieren
      
      isShared = true; 

      // Priorisierung des Status-Labels (Warnung bei öffentlichen Links)
      if (p.type === 'anyone') {
        statusLabel = p.allowFileDiscovery ? "⚠️ Öffentlich im Web" : "⚠️ Jeder mit Link";
      } else if (p.type === 'domain' && !statusLabel.includes("⚠️")) {
        statusLabel = "🏢 Domain / Firma";
      } else if ((p.type === 'user' || p.type === 'group')) {
        var email = p.emailAddress || "Gruppe/Unbekannt";
        userEmails.push(email);
      }
    }
  }

  // Fallback: Wenn Status noch "Privat" scheint, aber User drin sind
  if (statusLabel === "Privat" && userEmails.length > 0) {
    statusLabel = "🔒 Beschränkt (Personen)";
  }

  return {
    isShared: isShared,
    statusLabel: statusLabel,
    userList: userEmails.join(", ")
  };
}

 

4. Ergebnisse interpretieren

Das Skript nutzt eine Sicherheits-Logik bei der Anzeige: Es wird immer der "gefährlichste" (offenste) Status in der Spalte "Freigabe-Status" priorisiert.

Hier sind Beispiele, wie typische Szenarien in der Tabelle dargestellt werden:

Szenario A: Der Misch-Fall (Link + Person)

Situation: Ein Ordner ist per Link für jeden erreichbar ("Jeder mit Link"), aber zusätzlich wurde die Person kollege@extern.de explizit eingeladen.

  • Anzeige: Der Status warnt vor dem öffentlichen Link (da dies das größere Sicherheitsrisiko ist). Die E-Mail-Adresse wird trotzdem rechts gelistet, damit Sie wissen, wer Zugriff behält, falls Sie den Link entfernen.
Dateiname Typ Freigabe-Status Berechtigte Personen
**Projekt AlphaAlpha** Ordner **⚠️ Jeder mit LinkLink** `kollege@extern.dede`

Szenario B: Nur bestimmte Personen

Situation: Die Datei ist privat (kein öffentlicher Link), wurde aber gezielt mit Kollegen geteilt.

  • Anzeige: Der Status zeigt "Beschränkt", da nur explizit genannte Personen Zugriff haben.
Dateiname Typ Freigabe-Status Berechtigte Personen
**Gehaltsliste.pdfpdf** Datei **🔒 Beschränkt (Personen)** `chef@firma.de, buchhaltung@firma.dede`

Szenario C: Komplett Öffentlich

Situation: Die Datei ist im Web veröffentlicht und kann über Suchmaschinen (Google Suche) gefunden werden, ohne dass man den Link kennt.

Dateiname Typ Freigabe-Status Berechtigte Personen
**Webseite-LogoLogo** Datei **⚠️ Öffentlich im WebWeb**  

Szenario D: Firmenweiter Zugriff (Domain)

Situation: (Nur bei Google Workspace Business-Konten) Die Datei ist für jeden innerhalb der eigenen Organisation auffindbar/aufrufbar, aber nicht für Externe.

Dateiname Typ Freigabe-Status Berechtigte Personen
Urlaubsantrag**Urlaubsantrag** Datei **🏢 Domain / FirmaFirma**