Freudenthaler
Integration / Microsoft 365

SharePoint-Speicher automatisiert verwalten.

Wie du mit PowerShell und Node.js hunderte Microsoft Teams effizient und fehlerfrei managst, auch bei hohem Wachstum.

1. Das Problem: Speicher, der nicht mitwächst

Wenn dein Unternehmen Microsoft 365 nutzt und regelmäßig neue Teams erstellt, kennst du das: Die SharePoint-Speicherkapazität passt sich nicht automatisch an und muss manuell verwaltet werden.

Bei kleinen Organisationen geht das noch. Aber was, wenn hunderte neuer Teams pro Woche entstehen? Dann wird das Anpassen der Speichergrößen über das SharePoint-Admincenter schnell zur zeitraubenden - und fehleranfälligen - Aufgabe.

Wir bauen einen automatisierten Prozess: Setup mit PowerShell 7 und PnP.PowerShell, ein Automatisierungs-Script mit Zertifikatsauthentifizierung, ein Node.js-Worker für die kontinuierliche Überwachung - und ein Cronjob, der das Ganze in Bewegung hält.

Für wen ist das?

IT-Administratoren, SharePoint-Verantwortliche und alle, die ihre Microsoft-365-Umgebung effizienter verwalten wollen. Besonders relevant bei vielen Teams oder hoher Nutzerfluktuation.

Was du mitnimmst

  • Warum manuelle SharePoint-Speicherverwaltung bei Skalierung kippt
  • Setup von PowerShell 7 und PnP.PowerShell für moderne Authentifizierung
  • Ein Automatisierungs-Script mit Zertifikat statt Passwort
  • Integration in einen Node.js-Worker für kontinuierliche Überwachung

2. Warum sich das lohnt

Bevor wir eine Zeile Code schreiben, der wirtschaftliche Hebel, denn der macht aus einem Nice-to-have eine klare Entscheidung.

Zeitersparnis

Stunden manueller Arbeit werden zu Minuten automatisierter Prozesse.

Skalierbarkeit

Hunderte neue Teams pro Woche, ohne manuellen Eingriff.

Fehlerreduktion

Automatisierte Prozesse minimieren menschliche Fehler.

Transparenz

Protokollierung aller Änderungen für Audit-Zwecke.

Was die Speicherkosten treibt

SharePoint Online bringt 1 TB Basisspeicher pro Organisation plus 10 GB pro lizenziertem Benutzer (bis 25 TB pro Site). Reicht das nicht: ca. 0,20 €/GB pro Monat für zusätzlichen Speicher. Microsoft 365 Archive (für selten genutzte Daten) kostet ca. 0,05 €/GB pro Monat.

5 TB Mehrbedarf ≈ 1.000 € pro Monat.

Bei tausenden Teams summiert sich das schnell. Automatisierte Verwaltung heißt: aktiv genutzte Teams bekommen angemessenen Speicher, überdimensionierte Zuteilungen fallen weg. Der Hebel ist real, nicht kosmetisch.

3. Die Architektur in einem Satz

Ein Node.js-Worker erkennt über die Microsoft Graph API neue Teams, gleicht sie gegen die Datenbank ab und triggert pro Team ein PowerShell-Script, das das Speicherkontingent setzt. Klingt nach Umweg über PowerShell - ist aber Absicht:

Warum nicht die Microsoft Graph API allein? Die Graph API bietet aktuell keine direkte Unterstützung für die Anpassung von SharePoint-Speicherkontingenten. Deshalb übernimmt PnP.PowerShell den Speicher-Teil - vollautomatisch, getriggert durch den Worker, der Graph nur für die Team-Erkennung nutzt.

4. Voraussetzungen

1. PowerShell 7

PowerShell 7 ist erforderlich, um die benötigten Module zu nutzen.

bash
# Installation unter Ubuntu
wget -q https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y powershell

Weitere Installationsanleitungen in der offiziellen PowerShell-Dokumentation.

2. PnP.PowerShell

PnP.PowerShell bietet moderne Authentifizierungsoptionen und ermöglicht Automatisierung ohne manuelle Eingabe von Zugangsdaten.

powershell
# Installation von PnP.PowerShell
pwsh
Install-Module -Name PnP.PowerShell -Force

3. Azure AD App und Zertifikat

Damit das Script laufen kann, brauchst du eine Azure AD App mit:

  • Sites.FullControl.All (Anwendungsberechtigungen in SharePoint)
  • einem X.509-Zertifikat (selbstsigniert oder von einer Zertifizierungsstelle)
powershell
# Selbstsigniertes Zertifikat erstellen (Windows)
$cert = New-SelfSignedCertificate -Subject "CN=MeineAzureADApp" \
    -KeySpec Signature -KeyLength 2048 \
    -KeyExportPolicy Exportable \
    -HashAlgorithm SHA256 \
    -CertStoreLocation "Cert:\CurrentUser\My"

# Export des Zertifikats
Export-PfxCertificate -Cert $cert \
    -FilePath "C:\Pfad\Zu\meinerAzureADApp.pfx" \
    -Password (ConvertTo-SecureString -String "MeinPasswort" -Force -AsPlainText)

Export-Certificate -Cert $cert -FilePath "C:\Pfad\Zu\meinerAzureADApp.cer"

5. Schritt 1: Das Speicher-Script

Das folgende Script setzt Speicherkontingent und Warnungslimit für eine spezifische SharePoint-Seite. Die Authentifizierung läuft über das eben erstellte Zertifikat - kein Passwort im Klartext, kein interaktiver Login.

powershell
Param(
  [Parameter(Mandatory=$true)]
  [string]$SiteName,
  [Parameter(Mandatory=$true)]
  [int]$NewStorageGB,
  [Parameter(Mandatory=$true)]
  [int]$NewStorageWarningGB
)

Import-Module PnP.PowerShell

$Tenant = "DEIN_TENANT"
$AdminCenterURL = "https://$Tenant-admin.sharepoint.com"
$SiteURL        = "https://$Tenant.sharepoint.com/sites/$SiteName"
$ClientId       = "DEINE_CLIENT_ID"
$TenantId       = "DEINE_TENANT_ID"
$CertificatePath     = "./DeinZertifikat.pfx"
$CertificatePassword = ConvertTo-SecureString -String "DEIN_PASSWORT" -Force -AsPlainText

Connect-PnPOnline -Url $AdminCenterURL `
  -ClientId $ClientId -Tenant $TenantId `
  -CertificatePath $CertificatePath `
  -CertificatePassword $CertificatePassword

$NewStorageMB        = $NewStorageGB * 1024
$NewStorageWarningMB = $NewStorageWarningGB * 1024

Set-PnPSite -Identity $SiteURL `
  -StorageMaximumLevel $NewStorageMB `
  -StorageWarningLevel $NewStorageWarningMB

Disconnect-PnPOnline
Write-Host "Speicherkontingent fuer '$SiteName' angepasst." -ForegroundColor Green
Sicherheitshinweis: In produktiven Umgebungen gehören Passwörter nicht im Klartext ins Script. Nutze Azure Key Vault, Environment-Variablen oder Managed Identities. Das Zertifikat selbst schützt du mit eingeschränkten Dateirechten.

6. Schritt 2: Der Node.js-Worker

Der Worker ruft Teams über die Microsoft Graph API ab, prüft den Status in der Datenbank und führt das PowerShell-Script bei Bedarf aus. Node.js ist hier nur ein Beispiel - dieselbe Logik funktioniert in Python, Go oder .NET genauso.

javascript
const { exec } = require("child_process");
const fetch = require("node-fetch");

// Beispiel: Teams ohne Speicheranpassung aus der Datenbank holen
const database = {
  getTeamsWithoutStorageQuota: async () => [
    { teamName: "TeamA", teamId: "12345" },
  ],
};

const getSiteNameByTeamId = async (teamId) => {
  const token = "YOUR_ACCESS_TOKEN";
  const response = await fetch(
    `https://graph.microsoft.com/v1.0/groups/${teamId}/sites/root`,
    { headers: { Authorization: `Bearer ${token}` } }
  );
  if (!response.ok) throw new Error(`Fehler: ${response.statusText}`);
  const data = await response.json();
  return data.name;
};

const setStorageQuota = (siteName, storageGB, warningGB) => {
  const command = `pwsh ./setStorageQuota.ps1 -SiteName "${siteName}" ` +
    `-NewStorageGB ${storageGB} -NewStorageWarningGB ${warningGB}`;
  exec(command, (error, stdout, stderr) => {
    if (error)  return console.error(`Fehler: ${error.message}`);
    if (stderr) return console.error(`stderr: ${stderr}`);
    console.log(`stdout: ${stdout}`);
  });
};

(async () => {
  try {
    const teams = await database.getTeamsWithoutStorageQuota();
    for (const team of teams) {
      const siteName = await getSiteNameByTeamId(team.teamId);
      setStorageQuota(siteName, 100, 90);
    }
  } catch (error) {
    console.error(`Fehler im Worker: ${error.message}`);
  }
})();
Tipps für die Implementierung: Ergänze Logging, um alle Änderungen und Fehler zu protokollieren. Baue Retry-Mechanismen für zuverlässigere API-Aufrufe ein, lagere Werte in eine Konfigurationsdatei aus und schick dir Benachrichtigungen (Slack oder E-Mail) bei Fehlern.

7. Schritt 3: Dauerbetrieb per Cron

Für die kontinuierliche Überwachung lässt du den Worker per Cron regelmäßig laufen. So läuft der Prozess vollständig automatisiert, ohne dass jemand daran denken muss.

bash
0 0 * * * cd /pfad/zum/projekt && npm run start-worker >> /pfad/zum/logfile.log 2>&1

Der Eintrag führt den Worker täglich um Mitternacht aus und protokolliert die Ausgabe in eine Logdatei.

8. Vom Problem zur Lösung

Ein Kunde mit tausenden aktiven Teams: standardmäßige Speicherlimits führten immer wieder zu vollen Sites und Arbeitsunterbrechungen. 30-50 neue Teams pro Woche, die manuelle Verwaltung war eine enorme Belastung für die IT. Der direkte Vergleich:

Vorher

Manuelles Anpassen im SharePoint-Admincenter: ca. 3-4 Stunden pro Woche
Regelmäßige Support-Tickets wegen vollem Speicher: ca. 15 pro Woche
Fehleranfälliger Prozess mit inkonsistenten Speicherzuweisungen

Nachher

Vollautomatischer Prozess: Neue Teams bekommen sofort ausreichend Speicher
Support-Tickets wegen vollem Speicher: nahezu 0
IT-Zeitersparnis: über 150 Stunden pro Jahr
Konsistente Speicherzuweisungen nach definierten Regeln

Solche Routine-Tasks gehören aus der IT-Abteilung raus. Niemand sollte hunderte Mal pro Monat dasselbe Häkchen setzen.

9. Ehrliche Einordnung: Wo die Grenzen sind

Der gezeigte Ansatz ist bewusst schlank, ein Fundament, das du an einem Tag stehen hast. Bevor er unternehmensweit läuft, fehlen aber die Dinge, die im Betrieb den Unterschied machen:

Solides Fundament

Für einen abgegrenzten Tenant und ein Team, das die Scripts kennt, ist dieses Setup eine belastbare Basis. Es läuft, es ist nachvollziehbar, es spart sofort Zeit.

Für den Produktivbetrieb fehlt

  • Monitoring & Alerting bei Fehlern
  • Secret-Management (Key Vault statt Klartext)
  • Error-Recovery & Retry-Logik
  • Wartung bei API- & Modul-Updates

Diese Lücke schließen wir. Wir bauen solche Automatisierungen für den Mittelstand produktionsreif: mit Monitoring, sauberem Secret-Management, durchdachter Fehlerbehandlung und laufender Wartung - damit die Routine aus deiner IT-Abteilung verschwindet und nicht zum nächsten Wartungsfall wird.

Manuelle IT-Routinen, die du loswerden willst?

Ob SharePoint, Azure, M365 oder dein ERP - wir automatisieren die wiederkehrenden Verwaltungsaufgaben, die deine IT-Abteilung blockieren. Mit Monitoring, sauberem Secret-Management und Wartung.

Mehr Insights