In diesem Beitrag möchte ich euch zeigen, wie man mit einem simplen Skript, ein wenig Ordnung in die Domäne bringt. Das Skript beinhaltet mehrere Funktionen zum löschen und bereinigen von Verzeichnissen, Logs, Updates etc.
Folgende Funktionen sind enthalten:
✅ cleanup-mgr
✅ delete-folders
✅ clear-event-logs
✅ cleanup-windows-update
✅ update-group-policy
❌ cleanup-user-profiles
✅ cleanup-temp-files
✅ cleanup-dns-cache
❌ uninstall-softwarepackage
❌ get-installedsoftware
1️⃣. Funktion zum Loggen von Nachrichten in eine Datei
function Log-Message {
param (
[string]$Message,
[string]$Type = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$formattedMessage = "$timestamp [$Type] $Message"
Write-Output $formattedMessage | Out-File -FilePath "C:\temp\log\system_cleanup.log" -Append
# Optional: Protokoll auch zur Konsole ausgeben
Write-Output $formattedMessage
}
Zweck:
Diese Funktion ist das Herzstück der Protokollierung im Skript. Jeder Schritt der Systembereinigung wird hierüber dokumentiert.
Funktionsweise:
- Parameter:
$Message
: Der eigentliche Text der Meldung.$Type
: Der Typ der Nachricht (Standard: „INFO“, aber auch „ERROR“ oder „WARNING“ möglich).
- Ablauf:
- Es wird ein Zeitstempel erstellt, der dann zusammen mit dem Nachrichtentext und dem Typ formatiert wird.
- Der formattierte Text wird sowohl in eine Log-Datei geschrieben als auch (optional) in die Konsole ausgegeben.
- Nutzen:
- Durch die zentrale Log-Funktion können spätere Fehler oder unerwartete Systemzustände leichter nachvollzogen und analysiert werden.
2️⃣. Funktion zum Abrufen installierter Software
function get-installedsoftware {
param (
[string]$Name,
[string]$Version = $null
)
try {
Log-Message "Suche nach installierter Software: Name=$Name, Version=$Version"
$package = Get-Package -Provider Programs -IncludeWindowsInstaller -Name $Name
if ($Version) {
$package = $package | Where-Object { $_.Version -eq $Version }
}
Log-Message "Gefundene Pakete: $($package.Count)"
return $package
} catch {
Log-Message "Fehler beim Abrufen installierter Software: $_" "ERROR"
}
}
Zweck:
Mit dieser Funktion können installierte Softwarepakete abgefragt werden. Das ist hilfreich, wenn man z. B. den Status oder die Version einer bestimmten Software prüfen möchte.
Funktionsweise:
- Parameter:
$Name
: Der Name der gesuchten Software.$Version
: Optional, um gezielt nach einer bestimmten Version zu suchen.
- Ablauf:
- Vor der Suche wird eine Log-Meldung ausgegeben.
- Mittels
Get-Package
werden Pakete abgefragt, und – falls ein Versionsfilter gesetzt wurde – zusätzlich gefiltert. - Abschließend wird die Anzahl gefundener Pakete protokolliert und das Ergebnis zurückgegeben.
- Nutzen:
- Ermöglicht ein schnelles und automatisiertes Inventar der installierten Software.
3️⃣. Funktion zum Deinstallieren eines Softwarepakets
function uninstall-softwarepackage {
param (
[Microsoft.PackageManagement.Packaging.SoftwareIdentity]$Package
)
try {
Log-Message "Versuche Deinstallation des Pakets: $($Package.Name)"
if ($Package.ProviderName -eq "Programs") {
$xml = [xml]$Package.SwidTagText
$uninstallString = $xml.SoftwareIdentity.Meta.UninstallString
if ($uninstallString -match 'msiexec.* /i.*') {
$uninst = (($uninstallString -split ' ')[1] -replace '/I', '/X') + ' /qb'
Start-Process msiexec.exe -ArgumentList $uninst -Wait -NoNewWindow -ErrorAction Stop
} elseif (Test-Path -LiteralPath $uninstallString) {
Start-Process -FilePath $uninstallString -Wait -NoNewWindow -ErrorAction Stop
} elseif ($uninstallString -match 'msiexec.* /x.*') {
$uninst = ($uninstallString -split ' ')[1] + ' /qb'
Start-Process msiexec.exe -ArgumentList $uninst -Wait -NoNewWindow -ErrorAction Stop
}
Log-Message "Deinstallation erfolgreich: $($Package.Name)"
} else {
$Package | Uninstall-Package -ErrorAction Stop
Log-Message "Deinstallation erfolgreich über Provider: $($Package.Name)"
}
} catch {
Log-Message "Fehler bei der Deinstallation des Pakets: $_" "ERROR"
}
}
Zweck:
Diese Funktion dient der Deinstallation eines Softwarepakets. Sie ist so aufgebaut, dass sie unterschiedliche Deinstallationsszenarien abdeckt.
Funktionsweise:
- Parameter:
$Package
: Ein Objekt, das Informationen über das Softwarepaket enthält.
- Ablauf:
- Zunächst wird über die Log-Funktion vermerkt, welches Paket deinstalliert werden soll.
- Wird festgestellt, dass der Provider „Programs“ ist, wird der XML-Inhalt des Pakets ausgelesen, um den richtigen Deinstallationsbefehl zu ermitteln.
- Unterschiedliche Ansätze (z. B. Ersetzen von
/I
zu/X
bei MSI-Installationen oder direkter Aufruf eines externen Deinstallationsprogramms) werden durchlaufen. - Ist der Provider ein anderer, wird der generische Befehl
Uninstall-Package
genutzt. - Bei Erfolg oder im Fehlerfall wird eine entsprechende Log-Meldung ausgegeben.
- Nutzen:
- Sorgt für eine saubere Entfernung von Software und differenziert zwischen verschiedenen Deinstallationsmethoden.
4️⃣. Funktion zur Ausführung von Cleanmgr mit Voreinstellungen
function cleanup-mgr {
try {
Log-Message "Starte cleanup-mgr"
$regList = @(
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\BranchCache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\D3D Shader Cache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Delivery Optimization Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Diagnostic Data Viewer database files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Downloaded Program Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Internet Cache Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Language Pack"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Old ChkDsk Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Recycle Bin"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\RetailDemo Offline Content"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Setup Log Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\System error memory dump files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\System error minidump files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Temporary Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Update Cleanup"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\User file versions"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Defender"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Error Reporting Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Upgrade Log Files"; Key = 2 }
)
$keyname = 'StateFlags1337'
foreach($key in $regList) {
New-ItemProperty -Path $key.Pfad -Name $keyname -Value $key.Key -Type DWORD -Force | Out-Null
}
Start-Process "$env:SystemRoot\System32\cleanmgr.exe" -ArgumentList "/D C /verylowdisk /sagerun:1337" -WindowStyle Hidden
Log-Message "cleanup-mgr erfolgreich abgeschlossen"
} catch {
Log-Message "Fehler in cleanup-mgr: $_" "ERROR"
}
}
Zweck:
Diese Funktion nutzt den Windows „Cleanmgr“ (Datenträgerbereinigung) zur Entfernung von überflüssigen Systemdateien und Caches.
Funktionsweise:
Die Funktionsweise von cleanmgr könnt ihr bei Microsoft nachlesen: https://learn.microsoft.com/de-de/windows-server/administration/windows-commands/cleanmgr
- Ablauf:
- Es wird ein Array mit Registry-Pfaden definiert, die auf unterschiedliche Cache-Bereiche des Systems verweisen (z. B. Internet Cache, temporäre Dateien usw.).
- Für jeden Eintrag wird ein spezieller Registry-Wert (
StateFlags1337
) mit einem definierten Wert (0, 2 etc.) gesetzt – dies signalisiert Cleanmgr, welche Bereiche bereinigt werden sollen. - Anschließend wird Cleanmgr mit Parametern gestartet, die den Bereinigungsprozess automatisieren (z. B.
"/sagerun:1337"
für die zuvor definierten Einstellungen). - Alle Schritte werden geloggt.
- Nutzen:
- Ermöglicht eine automatisierte und konsistente Bereinigung des Systems, um Speicherplatz freizugeben und die Leistung zu optimieren.
5️⃣. Funktion zum Löschen bestimmter Ordner
function delete-folders {
try {
Log-Message "Starte delete-folders"
$chocoPath = 'C:\ProgramData\choco-cache\'
$adobeARM = 'C:\ProgramData\Adobe\ARM\'
if ((Get-ChildItem -Path $chocoPath -ErrorAction SilentlyContinue | Measure-Object -ErrorAction SilentlyContinue -Property Length -Sum).Sum /1MB -ge 100) {
Remove-Item -Path "$chocoPath*" -Recurse -Force
Log-Message "Chocolatey Cache gelöscht"
}
if (Test-Path -Path $adobeARM) {
Remove-Item -Path "$adobeARM*" -Recurse -Force
Log-Message "Adobe ARM-Daten gelöscht"
}
} catch {
Log-Message "Fehler in delete-folders: $_" "ERROR"
}
}
Zweck:
Mit dieser Funktion werden gezielt bestimmte Ordner gelöscht – hier etwa der Chocolatey-Cache und Adobe ARM-Daten.
Funktionsweise:
- Ablauf:
- Zunächst wird der Pfad des Chocolatey-Caches überprüft. Liegt dessen Größe über einem definierten Schwellenwert (hier 100 MB), wird der gesamte Inhalt gelöscht.
- Ebenso wird der Adobe ARM-Pfad überprüft und – falls vorhanden – geleert.
- Beide Aktionen werden protokolliert.
- Nutzen:
- Reduziert den unnötig belegten Speicherplatz durch veraltete oder temporäre Cache-Daten.
6️⃣. Funktion zur Bereinigung von Event-Logs
function clear-event-logs {
try {
Log-Message "Starte clear-event-logs"
$threeMonthsAgo = (Get-Date).AddMonths(-4)
# Liste aller Event-Logs
$eventLogs = Get-WinEvent -ListLog * | Where { $_.RecordCount -gt 0}
foreach ($log in $eventLogs) {
$logName = $log.LogName
try {
# Prüfen, wann das letzte Ereignis erstellt wurde
$latestEvent = Get-WinEvent -LogName $logName -MaxEvents 1 -ErrorAction Stop
if ($latestEvent) {
$latestEventTime = $latestEvent.TimeCreated
if ($latestEventTime -lt $threeMonthsAgo) {
# Log löschen, wenn das letzte Ereignis älter als 3 Monate ist
Clear-EventLog -LogName $logName
Log-Message "Event-Log $logName erfolgreich bereinigt"
}
}
} catch {
# Wenn keine Ereignisse gefunden werden, überspringen
if ($_.Exception -is [System.Management.Automation.RuntimeException]) {
Log-Message "Keine Ereignisse im Log $logName gefunden oder Fehler beim Abrufen der Ereignisse: $_" "WARNING"
} else {
Log-Message "Fehler beim Abrufen von Ereignissen im Log $logName : $_" "ERROR"
}
}
}
} catch {
Log-Message "Fehler in clear-event-logs: $_" "ERROR"
}
}
Zweck:
Event-Logs können über längere Zeiträume wachsen und unnötig Speicher belegen. Diese Funktion löscht jene Logs, die über einen definierten Zeitraum (hier: älter als ca. 4 Monate) nicht aktualisiert wurden.
Funktionsweise:
- Ablauf:
- Es wird ein Schwellenwert-Datum berechnet, das angibt, ab wann Logs als „alt“ gelten.
- Mit
Get-WinEvent
werden alle Event-Logs abgefragt, die Einträge enthalten. - Für jedes Log wird das Datum des letzten Eintrags überprüft.
- Sind die Logs „veraltet“, wird
Clear-EventLog
aufgerufen, um den Inhalt zu löschen. - Besondere Fehlerfälle (z. B. wenn keine Ereignisse vorhanden sind) werden separat behandelt und geloggt.
- Nutzen:
- Sorgt dafür, dass alte und nicht mehr relevante Log-Daten entfernt werden – ein wichtiger Schritt zur Systemwartung und zur Einsparung von Festplattenspeicher.
7️⃣. Funktion zur Bereinigung des Windows Update Caches
function cleanup-windows-update {
try {
Log-Message "Starte cleanup-windows-update"
net stop wuauserv
Remove-Item -LiteralPath "C:\Windows\SoftwareDistribution\*" -Recurse -Force
net start wuauserv
Log-Message "Windows Update Cache erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-windows-update: $_" "ERROR"
}
}
Zweck:
Diese Funktion räumt den Windows Update-Cache auf, der sich mit der Zeit ansammeln und potenziell zu fehlerhaften Update-Vorgängen führen kann.
Funktionsweise:
- Ablauf:
- Der Windows Update Service (
wuauserv
) wird gestoppt, um sicherzustellen, dass keine Dateien in Benutzung sind. - Der Inhalt des Ordners
C:\Windows\SoftwareDistribution\*
wird gelöscht. - Anschließend wird der Dienst wieder gestartet.
- Alle Schritte werden im Log dokumentiert.
- Der Windows Update Service (
- Nutzen:
- Hilft bei der Behebung von Update-Problemen und stellt sicher, dass der Update-Cache stets auf dem neuesten Stand ist.
8️⃣. Funktion zur Aktualisierung von Gruppenrichtlinien
function update-group-policy {
try {
Log-Message "Starte update-group-policy"
gpupdate /force
Log-Message "Gruppenrichtlinien erfolgreich aktualisiert"
} catch {
Log-Message "Fehler in update-group-policy: $_" "ERROR"
}
}
Zweck:
Mit dieser Funktion werden Gruppenrichtlinien sofort aktualisiert, sodass alle Änderungen unverzüglich wirksam werden.
Funktionsweise:
- Ablauf:
- Der Befehl
gpupdate /force
wird ausgeführt, um alle Gruppenrichtlinien zu aktualisieren. - Erfolgreiche Aktualisierungen sowie etwaige Fehler werden geloggt.
- Der Befehl
- Nutzen:
- Stellt sicher, dass alle aktuellen Richtlinien (z. B. Sicherheits- und Konfigurationsvorgaben) auf dem System aktiv sind.
9️⃣. Funktion zur Bereinigung alter Benutzerprofile
function cleanup-user-profiles {
try {
Log-Message "Starte cleanup-user-profiles"
$profilesToDelete = Get-WmiObject -Class Win32_UserProfile | Where-Object {
$_.Special -eq $false -and $_.LastUseTime -lt ((Get-Date).AddDays(-6000)).ToFileTime()
}
foreach ($profile in $profilesToDelete) {
Remove-WmiObject -InputObject $profile
Log-Message "Benutzerprofil gelöscht: $($profile.LocalPath)"
}
Log-Message "Alte Benutzerprofile erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-user-profiles: $_" "ERROR"
}
}
Zweck:
Diese Funktion entfernt alte Benutzerprofile, die seit langer Zeit nicht mehr verwendet wurden – etwa von ehemaligen Mitarbeitern oder inaktiven Nutzern.
Funktionsweise:
- Ablauf:
- Mithilfe von
Get-WmiObject
und der KlasseWin32_UserProfile
werden alle Benutzerprofile abgefragt. - Es werden nur Profile berücksichtigt, die nicht als „Special“ markiert sind und deren letzter Nutzungszeitpunkt (LastUseTime) vor einem bestimmten Datum liegt.
- Jedes gefundene Profil wird mittels
Remove-WmiObject
gelöscht. - Jeder Löschvorgang wird protokolliert.
- Mithilfe von
- Nutzen:
- Bereinigt das System von überflüssigen Benutzerprofilen, was zu einer verbesserten Systemleistung und einer geringeren Fragmentierung der Benutzerverzeichnisse führt.
1️⃣0️⃣. Funktion zur Bereinigung temporärer Dateien
function cleanup-temp-files {
try {
Log-Message "Starte cleanup-temp-files"
Remove-Item -LiteralPath "C:\Windows\Temp\*" -Recurse -Force
Remove-Item -LiteralPath "$env:TEMP\*" -Recurse -Force
Log-Message "Temporäre Dateien erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-temp-files: $_" "ERROR"
}
}
Zweck:
Diese Funktion löscht temporäre Dateien, die sich sowohl im Windows-Temp-Ordner als auch im benutzerspezifischen Temp-Verzeichnis angesammelt haben.
Funktionsweise:
- Ablauf:
- Es werden die Inhalte des Systemordners
C:\Windows\Temp\*
sowie des benutzerspezifischen Temp-Ordners ($env:TEMP\*
) rekursiv gelöscht. - Auch hier sorgt die Fehlerbehandlung dafür, dass eventuelle Probleme im Löschvorgang geloggt werden.
- Es werden die Inhalte des Systemordners
- Nutzen:
- Durch das Entfernen von temporären Dateien wird unnötig belegter Speicher freigegeben und das System bleibt „sauber“, was wiederum die Performance verbessert.
1️⃣1️⃣. Funktion zur Bereinigung des DNS-Caches
function cleanup-dns-cache {
try {
Log-Message "Starte cleanup-dns-cache"
Clear-DnsClientCache
Log-Message "DNS-Cache erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-dns-cache: $_" "ERROR"
}
}
Zweck:
Mit dieser Funktion wird der DNS-Cache geleert, um veraltete DNS-Einträge zu entfernen und so mögliche Netzwerkprobleme (z. B. falsche Namensauflösung) zu vermeiden.
Funktionsweise:
- Ablauf:
- Der Befehl
Clear-DnsClientCache
wird ausgeführt, um alle zwischengespeicherten DNS-Einträge zu löschen. - Erfolg oder Fehler werden ebenfalls protokolliert.
- Der Befehl
- Nutzen:
- Hilft bei der Behebung von Netzwerkproblemen, wenn DNS-Einträge aktualisiert wurden, aber der alte Cache weiterhin verwendet wird.
1️⃣2️⃣. Hauptfunktion zur Reinigung des Systems
function cleanup {
try {
Log-Message "Starte Systembereinigung"
cleanup-mgr
delete-folders
clear-event-logs
cleanup-windows-update
update-group-policy
#cleanup-user-profiles
cleanup-temp-files
cleanup-dns-cache
Log-Message "Systembereinigung erfolgreich abgeschlossen"
} catch {
Log-Message "Fehler in cleanup: $_" "ERROR"
}
}
# Ausführung der Systembereinigung
cleanup
Zweck:
Diese zentrale Funktion orchestriert die Ausführung aller einzelnen Bereinigungsroutinen, um eine umfassende Systemwartung in einem Durchgang zu ermöglichen.
Funktionsweise:
- Ablauf:
- Zu Beginn wird eine Log-Meldung ausgegeben, die den Start der Systembereinigung signalisiert.
- Nacheinander werden alle vorher definierten Funktionen (wie
cleanup-mgr
,delete-folders
,clear-event-logs
,cleanup-windows-update
,update-group-policy
,cleanup-temp-files
undcleanup-dns-cache
) aufgerufen. - (Hinweis: Die Funktion
cleanup-user-profiles
ist auskommentiert – je nach Bedarf kann sie aktiviert werden.) - Abschließend wird ein Log-Eintrag erstellt, der den erfolgreichen Abschluss der Bereinigung bestätigt.
- Nutzen:
- Sorgt für einen strukturierten und automatisierten Ablauf, der alle wichtigen Wartungsaufgaben zusammenfasst.
Das Komplette Skript sieht dann wie folgt aus:
# Funktion zum Loggen von Nachrichten in eine Datei
function Log-Message {
param (
[string]$Message,
[string]$Type = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$formattedMessage = "$timestamp [$Type] $Message"
Write-Output $formattedMessage | Out-File -FilePath "C:\temp\log\system_cleanup.log" -Append
# Optional: Protokoll auch zur Konsole ausgeben
Write-Output $formattedMessage
}
# Funktion zum Abrufen installierter Software
function get-installedsoftware {
param (
[string]$Name,
[string]$Version = $null
)
try {
Log-Message "Suche nach installierter Software: Name=$Name, Version=$Version"
$package = Get-Package -Provider Programs -IncludeWindowsInstaller -Name $Name
if ($Version) {
$package = $package | Where-Object { $_.Version -eq $Version }
}
Log-Message "Gefundene Pakete: $($package.Count)"
return $package
} catch {
Log-Message "Fehler beim Abrufen installierter Software: $_" "ERROR"
}
}
# Funktion zum Deinstallieren eines Softwarepakets
function uninstall-softwarepackage {
param (
[Microsoft.PackageManagement.Packaging.SoftwareIdentity]$Package
)
try {
Log-Message "Versuche Deinstallation des Pakets: $($Package.Name)"
if ($Package.ProviderName -eq "Programs") {
$xml = [xml]$Package.SwidTagText
$uninstallString = $xml.SoftwareIdentity.Meta.UninstallString
if ($uninstallString -match 'msiexec.* /i.*') {
$uninst = (($uninstallString -split ' ')[1] -replace '/I', '/X') + ' /qb'
Start-Process msiexec.exe -ArgumentList $uninst -Wait -NoNewWindow -ErrorAction Stop
} elseif (Test-Path -LiteralPath $uninstallString) {
Start-Process -FilePath $uninstallString -Wait -NoNewWindow -ErrorAction Stop
} elseif ($uninstallString -match 'msiexec.* /x.*') {
$uninst = ($uninstallString -split ' ')[1] + ' /qb'
Start-Process msiexec.exe -ArgumentList $uninst -Wait -NoNewWindow -ErrorAction Stop
}
Log-Message "Deinstallation erfolgreich: $($Package.Name)"
} else {
$Package | Uninstall-Package -ErrorAction Stop
Log-Message "Deinstallation erfolgreich über Provider: $($Package.Name)"
}
} catch {
Log-Message "Fehler bei der Deinstallation des Pakets: $_" "ERROR"
}
}
# Funktion zur Ausführung von Cleanmgr mit Voreinstellungen
function cleanup-mgr {
try {
Log-Message "Starte cleanup-mgr"
$regList = @(
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\BranchCache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\D3D Shader Cache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Delivery Optimization Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Diagnostic Data Viewer database files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Downloaded Program Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Internet Cache Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Language Pack"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Old ChkDsk Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Recycle Bin"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\RetailDemo Offline Content"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Setup Log Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\System error memory dump files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\System error minidump files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Temporary Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Update Cleanup"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\User file versions"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Defender"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Error Reporting Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Upgrade Log Files"; Key = 2 }
)
$keyname = 'StateFlags1337'
foreach($key in $regList) {
New-ItemProperty -Path $key.Pfad -Name $keyname -Value $key.Key -Type DWORD -Force | Out-Null
}
Start-Process "$env:SystemRoot\System32\cleanmgr.exe" -ArgumentList "/D C /verylowdisk /sagerun:1337" -WindowStyle Hidden
Log-Message "cleanup-mgr erfolgreich abgeschlossen"
} catch {
Log-Message "Fehler in cleanup-mgr: $_" "ERROR"
}
}
# Funktion zum Löschen bestimmter Ordner
function delete-folders {
try {
Log-Message "Starte delete-folders"
$chocoPath = 'C:\ProgramData\choco-cache\'
$adobeARM = 'C:\ProgramData\Adobe\ARM\'
if ((Get-ChildItem -Path $chocoPath -ErrorAction SilentlyContinue | Measure-Object -ErrorAction SilentlyContinue -Property Length -Sum).Sum /1MB -ge 100) {
Remove-Item -Path "$chocoPath*" -Recurse -Force
Log-Message "Chocolatey Cache gelöscht"
}
if (Test-Path -Path $adobeARM) {
Remove-Item -Path "$adobeARM*" -Recurse -Force
Log-Message "Adobe ARM-Daten gelöscht"
}
} catch {
Log-Message "Fehler in delete-folders: $_" "ERROR"
}
}
# Funktion zur Bereinigung von Event-Logs
function clear-event-logs {
try {
Log-Message "Starte clear-event-logs"
$threeMonthsAgo = (Get-Date).AddMonths(-4)
# Liste aller Event-Logs
$eventLogs = Get-WinEvent -ListLog * | Where { $_.RecordCount -gt 0}
foreach ($log in $eventLogs) {
$logName = $log.LogName
try {
# Prüfen, wann das letzte Ereignis erstellt wurde
$latestEvent = Get-WinEvent -LogName $logName -MaxEvents 1 -ErrorAction Stop
if ($latestEvent) {
$latestEventTime = $latestEvent.TimeCreated
if ($latestEventTime -lt $threeMonthsAgo) {
# Log löschen, wenn das letzte Ereignis älter als 3 Monate ist
Clear-EventLog -LogName $logName
Log-Message "Event-Log $logName erfolgreich bereinigt"
}
}
} catch {
# Wenn keine Ereignisse gefunden werden, überspringen
if ($_.Exception -is [System.Management.Automation.RuntimeException]) {
Log-Message "Keine Ereignisse im Log $logName gefunden oder Fehler beim Abrufen der Ereignisse: $_" "WARNING"
} else {
Log-Message "Fehler beim Abrufen von Ereignissen im Log $logName : $_" "ERROR"
}
}
}
} catch {
Log-Message "Fehler in clear-event-logs: $_" "ERROR"
}
}
# Funktion zur Bereinigung des Windows Update Caches
function cleanup-windows-update {
try {
Log-Message "Starte cleanup-windows-update"
net stop wuauserv
Remove-Item -LiteralPath "C:\Windows\SoftwareDistribution\*" -Recurse -Force
net start wuauserv
Log-Message "Windows Update Cache erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-windows-update: $_" "ERROR"
}
}
# Funktion zur Aktualisierung von Gruppenrichtlinien
function update-group-policy {
try {
Log-Message "Starte update-group-policy"
gpupdate /force
Log-Message "Gruppenrichtlinien erfolgreich aktualisiert"
} catch {
Log-Message "Fehler in update-group-policy: $_" "ERROR"
}
}
# Funktion zur Bereinigung alter Benutzerprofile
function cleanup-user-profiles {
try {
Log-Message "Starte cleanup-user-profiles"
$profilesToDelete = Get-WmiObject -Class Win32_UserProfile | Where-Object {
$_.Special -eq $false -and $_.LastUseTime -lt ((Get-Date).AddDays(-6000)).ToFileTime()
}
foreach ($profile in $profilesToDelete) {
Remove-WmiObject -InputObject $profile
Log-Message "Benutzerprofil gelöscht: $($profile.LocalPath)"
}
Log-Message "Alte Benutzerprofile erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-user-profiles: $_" "ERROR"
}
}
# Funktion zur Bereinigung temporärer Dateien
function cleanup-temp-files {
try {
Log-Message "Starte cleanup-temp-files"
Remove-Item -LiteralPath "C:\Windows\Temp\*" -Recurse -Force
Remove-Item -LiteralPath "$env:TEMP\*" -Recurse -Force
Log-Message "Temporäre Dateien erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-temp-files: $_" "ERROR"
}
}
# Funktion zur Bereinigung des DNS-Caches
function cleanup-dns-cache {
try {
Log-Message "Starte cleanup-dns-cache"
Clear-DnsClientCache
Log-Message "DNS-Cache erfolgreich bereinigt"
} catch {
Log-Message "Fehler in cleanup-dns-cache: $_" "ERROR"
}
}
# Hauptfunktion zur Reinigung des Systems
function cleanup {
try {
Log-Message "Starte Systembereinigung"
cleanup-mgr
delete-folders
clear-event-logs
cleanup-windows-update
update-group-policy
#cleanup-user-profiles
cleanup-temp-files
cleanup-dns-cache
Log-Message "Systembereinigung erfolgreich abgeschlossen"
} catch {
Log-Message "Fehler in cleanup: $_" "ERROR"
}
}
# Ausführung der Systembereinigung
cleanup
Wenn man das Ganze noch etwas aufhübscht, die comment-based Hilfe hinzufügt und das logging erweitert, erhält man ein gutes und leicht verständliches Skript.
<#
.SYNOPSIS
System-Cleanup-Skript für Windows-Systeme.
.DESCRIPTION
Dieses Skript führt verschiedene Reinigungsoperationen auf einem Windows-System durch,
einschließlich Entfernung temporärer Dateien, Bereinigung des Disk Space Manager,
Löschen des Windows Update-Caches, Bereinigung von Event-Logs und mehr.
.NOTES
Dateiname: system_cleanup.ps1
Autor: Ismahiil Ahmed
Version: 1.1
Datum: 2025-03-11
Voraussetzungen: PowerShell 5.1 oder höher, Administratorrechte
.EXAMPLE
.\system_cleanup.ps1
Führt alle Bereinigungsoperationen durch.
#>
# Stellen Sie sicher, dass das Protokollverzeichnis existiert
$logPath = "C:\temp\log"
if (-not (Test-Path -Path $logPath)) {
New-Item -Path $logPath -ItemType Directory -Force | Out-Null
}
<#
.SYNOPSIS
Protokolliert Nachrichten in eine Datei.
.DESCRIPTION
Protokolliert Nachrichten mit Zeitstempel und Typ in eine Protokolldatei
und gibt sie optional auch in der Konsole aus.
.PARAMETER Message
Die zu protokollierende Nachricht.
.PARAMETER Type
Der Nachrichtentyp (z.B. INFO, WARNING, ERROR).
.EXAMPLE
Log-Message "Operation abgeschlossen" "INFO"
Protokolliert "Operation abgeschlossen" als INFO-Nachricht.
#>
function Log-Message {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$Message,
[Parameter(Mandatory = $false, Position = 1)]
[ValidateSet("INFO", "WARNING", "ERROR", "SUCCESS")]
[string]$Type = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$formattedMessage = "$timestamp [$Type] $Message"
# Stellen Sie sicher, dass die Protokolldatei existiert
$logFile = "C:\temp\log\system_cleanup.log"
if (-not (Test-Path -Path $logFile)) {
New-Item -Path $logFile -ItemType File -Force | Out-Null
}
Add-Content -Path $logFile -Value $formattedMessage
# Farbcodierung für Konsolenausgabe
switch ($Type) {
"INFO" { Write-Host $formattedMessage -ForegroundColor Cyan }
"WARNING" { Write-Host $formattedMessage -ForegroundColor Yellow }
"ERROR" { Write-Host $formattedMessage -ForegroundColor Red }
"SUCCESS" { Write-Host $formattedMessage -ForegroundColor Green }
default { Write-Host $formattedMessage }
}
}
<#
.SYNOPSIS
Ruft installierte Software ab.
.DESCRIPTION
Sucht nach installierter Software anhand des Namens und optional der Version.
.PARAMETER Name
Der Name der zu suchenden Software. Unterstützt Platzhalter (*).
.PARAMETER Version
Optional: Die spezifische Version der zu suchenden Software.
.EXAMPLE
get-installedsoftware "Adobe*"
Gibt alle installierten Adobe-Softwarepakete zurück.
.EXAMPLE
get-installedsoftware "Microsoft Office" "16.0.12345.67890"
Gibt Microsoft Office mit der angegebenen Version zurück, falls installiert.
.OUTPUTS
Microsoft.PackageManagement.Packaging.SoftwareIdentity
Ein oder mehrere Softwareidentitätsobjekte, die der Suche entsprechen.
#>
function get-installedsoftware {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string]$Name,
[Parameter(Mandatory = $false, Position = 1)]
[string]$Version = $null
)
try {
Log-Message "Suche nach installierter Software: Name=$Name, Version=$Version"
# Hole alle Pakete, die dem Namen entsprechen
$packages = Get-Package -Provider Programs -IncludeWindowsInstaller -Name $Name -ErrorAction Stop
# Filtere nach Version, falls angegeben
if ($Version) {
$packages = $packages | Where-Object { $_.Version -eq $Version }
}
$count = if ($packages) { $packages.Count } else { 0 }
Log-Message "Gefundene Pakete: $count"
return $packages
}
catch {
Log-Message "Fehler beim Abrufen installierter Software: $_" "ERROR"
return $null
}
}
<#
.SYNOPSIS
Deinstalliert ein Softwarepaket.
.DESCRIPTION
Deinstalliert ein Softwarepaket basierend auf dem übergebenen Paketobjekt.
Unterstützt verschiedene Deinstallationsmethoden je nach Pakettyp.
.PARAMETER Package
Das zu deinstallierende Softwarepaket (SoftwareIdentity-Objekt).
.EXAMPLE
$office = get-installedsoftware "Microsoft Office"
uninstall-softwarepackage $office
Deinstalliert Microsoft Office.
.NOTES
Diese Funktion erfordert Administratorrechte.
#>
function uninstall-softwarepackage {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, Position = 0)]
[Microsoft.PackageManagement.Packaging.SoftwareIdentity]$Package
)
try {
Log-Message "Versuche Deinstallation des Pakets: $($Package.Name) (Version: $($Package.Version))"
# Prüfe, ob es sich um ein Programm handelt
if ($Package.ProviderName -eq "Programs") {
# Extrahiere Deinstallationsinformationen aus SWID-Tag
$xml = [xml]$Package.SwidTagText
$uninstallString = $xml.SoftwareIdentity.Meta.UninstallString
Log-Message "Deinstallationsstring: $uninstallString" "INFO"
# Verarbeite je nach Art des Deinstallationsstrings
if ($uninstallString -match 'msiexec.* /[iI].*') {
# MSI-Deinstallation (ersetze /I durch /X für Deinstallation)
$uninst = (($uninstallString -split ' ')[1] -replace '/[iI]', '/X') + ' /qb'
Log-Message "Führe MSI-Deinstallation aus: msiexec.exe $uninst"
Start-Process msiexec.exe -ArgumentList $uninst -Wait -NoNewWindow -ErrorAction Stop
}
elseif ($uninstallString -match 'msiexec.* /[xX].*') {
# MSI-Deinstallation (bereits mit /X)
$uninst = ($uninstallString -split ' ')[1] + ' /qb'
Log-Message "Führe MSI-Deinstallation aus: msiexec.exe $uninst"
Start-Process msiexec.exe -ArgumentList $uninst -Wait -NoNewWindow -ErrorAction Stop
}
elseif (Test-Path -LiteralPath $uninstallString -ErrorAction SilentlyContinue) {
# Ausführbare Deinstallationsdatei
Log-Message "Führe Deinstallationsprogramm aus: $uninstallString"
Start-Process -FilePath $uninstallString -Wait -NoNewWindow -ErrorAction Stop
}
else {
# Versuche, den Deinstallationsstring direkt auszuführen
Log-Message "Versuche direkten Aufruf des Deinstallationsstrings"
Invoke-Expression $uninstallString
}
Log-Message "Deinstallation erfolgreich: $($Package.Name)" "SUCCESS"
}
else {
# Für andere Provider (z.B. PowerShellGet, Chocolatey)
Log-Message "Deinstalliere über Paketprovider: $($Package.ProviderName)"
$Package | Uninstall-Package -Force -ErrorAction Stop
Log-Message "Deinstallation erfolgreich über Provider: $($Package.Name)" "SUCCESS"
}
}
catch {
Log-Message "Fehler bei der Deinstallation des Pakets: $_" "ERROR"
}
}
<#
.SYNOPSIS
Führt den Windows Disk Cleanup Manager mit vordefinierten Einstellungen aus.
.DESCRIPTION
Konfiguriert und startet den Windows Disk Cleanup Manager (cleanmgr.exe) mit
vordefinierten Einstellungen zur Bereinigung verschiedener Systemdateien.
.EXAMPLE
cleanup-mgr
Führt den Disk Cleanup Manager mit den vordefinierten Einstellungen aus.
.NOTES
Diese Funktion erfordert Administratorrechte.
Ein Wert von 2 bedeutet, dass diese Kategorie zur Bereinigung ausgewählt wird.
#>
function cleanup-mgr {
[CmdletBinding()]
param ()
try {
Log-Message "Starte cleanup-mgr"
# Definiere die zu bereinigenden Kategorien
$regList = @(
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\BranchCache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\D3D Shader Cache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Delivery Optimization Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Diagnostic Data Viewer database files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Downloaded Program Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Internet Cache Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Language Pack"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Old ChkDsk Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Recycle Bin"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\RetailDemo Offline Content"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Setup Log Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\System error memory dump files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\System error minidump files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Temporary Files"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Thumbnail Cache"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Update Cleanup"; Key = 2 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\User file versions"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Defender"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Error Reporting Files"; Key = 0 },
@{ Pfad = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Windows Upgrade Log Files"; Key = 2 }
)
# Verwende einen eindeutigen Namen für den Cleanup-Lauf
$keyname = 'StateFlags1337'
# Setze die Registry-Einträge für jede Kategorie
foreach($key in $regList) {
# Prüfe, ob Registry-Pfad existiert, und erstelle ihn ggf.
if (-not (Test-Path -Path $key.Pfad)) {
New-Item -Path $key.Pfad -Force | Out-Null
}
# Setze oder aktualisiere den Registry-Wert
New-ItemProperty -Path $key.Pfad -Name $keyname -Value $key.Key -Type DWORD -Force | Out-Null
}
# Starte den Disk Cleanup Manager
Log-Message "Starte cleanmgr.exe mit vordefinierten Einstellungen"
Start-Process -FilePath "$env:SystemRoot\System32\cleanmgr.exe" -ArgumentList "/D C /verylowdisk /sagerun:1337" -WindowStyle Hidden -Wait
Log-Message "cleanup-mgr erfolgreich abgeschlossen" "SUCCESS"
}
catch {
Log-Message "Fehler in cleanup-mgr: $_" "ERROR"
}
}
<#
.SYNOPSIS
Löscht spezifische Cache-Ordner und temporäre Dateien.
.DESCRIPTION
Löscht den Chocolatey-Cache und Adobe ARM-Daten, wenn sie vorhanden sind
und bestimmte Größenbedingungen erfüllen.
.EXAMPLE
delete-folders
Löscht Chocolatey-Cache und Adobe ARM-Daten, falls sie existieren.
#>
function delete-folders {
[CmdletBinding()]
param ()
try {
Log-Message "Starte delete-folders"
# Definiere zu prüfende Pfade
$foldersToCheck = @(
@{
Path = 'C:\ProgramData\choco-cache\';
Name = "Chocolatey Cache";
SizeThreshold = 100; # in MB
CheckSize = $true;
},
@{
Path = 'C:\ProgramData\Adobe\ARM\';
Name = "Adobe ARM-Daten";
CheckSize = $false;
}
)
# Prüfe und lösche jeden Ordner gemäß den Bedingungen
foreach ($folder in $foldersToCheck) {
if (Test-Path -Path $folder.Path) {
$shouldDelete = $true
# Prüfe Größe, falls erforderlich
if ($folder.CheckSize) {
$size = (Get-ChildItem -Path $folder.Path -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB
if ($size -lt $folder.SizeThreshold) {
Log-Message "$($folder.Name) ist kleiner als $($folder.SizeThreshold) MB (aktuell: $([math]::Round($size, 2)) MB), wird übersprungen" "INFO"
$shouldDelete = $false
}
else {
Log-Message "$($folder.Name) hat die Größe von $([math]::Round($size, 2)) MB" "INFO"
}
}
# Lösche den Ordner, wenn die Bedingungen erfüllt sind
if ($shouldDelete) {
Remove-Item -Path "$($folder.Path)*" -Recurse -Force -ErrorAction Stop
Log-Message "$($folder.Name) erfolgreich gelöscht" "SUCCESS"
}
}
else {
Log-Message "$($folder.Name) nicht gefunden, Überspringen" "INFO"
}
}
Log-Message "delete-folders abgeschlossen" "SUCCESS"
}
catch {
Log-Message "Fehler in delete-folders: $_" "ERROR"
}
}
<#
.SYNOPSIS
Bereinigt Windows-Event-Logs, die älter als ein bestimmter Zeitraum sind.
.DESCRIPTION
Identifiziert Event-Logs, deren letzter Eintrag älter als vier Monate ist,
und löscht deren Inhalt.
.EXAMPLE
clear-event-logs
Bereinigt alle Event-Logs, deren letzte Einträge älter als vier Monate sind.
.NOTES
Diese Funktion erfordert Administratorrechte.
#>
function clear-event-logs {
[CmdletBinding()]
param ()
try {
Log-Message "Starte clear-event-logs"
# Definiere den Grenzwert (vier Monate zurück)
$threeMonthsAgo = (Get-Date).AddMonths(-4)
Log-Message "Lösche Event-Logs mit Einträgen älter als $($threeMonthsAgo.ToString('yyyy-MM-dd'))" "INFO"
# Hole alle Event-Logs mit Einträgen
$eventLogs = Get-WinEvent -ListLog * -ErrorAction SilentlyContinue |
Where-Object { $_.RecordCount -gt 0 -and $_.IsEnabled -and $_.IsLogFull -eq $false }
$clearedCount = 0
$skippedCount = 0
$errorCount = 0
foreach ($log in $eventLogs) {
$logName = $log.LogName
try {
# Prüfe, wann das letzte Ereignis erstellt wurde
$latestEvent = Get-WinEvent -LogName $logName -MaxEvents 1 -ErrorAction Stop
if ($latestEvent) {
$latestEventTime = $latestEvent.TimeCreated
if ($latestEventTime -lt $threeMonthsAgo) {
# Log löschen, wenn das letzte Ereignis älter als die Grenze ist
[System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog($logName)
$clearedCount++
Log-Message "Event-Log '$logName' erfolgreich bereinigt (letzter Eintrag: $($latestEventTime.ToString('yyyy-MM-dd')))" "SUCCESS"
}
else {
$skippedCount++
Log-Message "Event-Log '$logName' übersprungen (letzter Eintrag: $($latestEventTime.ToString('yyyy-MM-dd')))" "INFO"
}
}
}
catch {
$errorCount++
# Wenn keine Ereignisse gefunden werden oder andere Fehler auftreten
if ($_.Exception -is [System.Management.Automation.RuntimeException] -or
$_.Exception.Message -match "No events") {
Log-Message "Keine Ereignisse im Log '$logName' gefunden oder unzureichende Berechtigungen" "WARNING"
}
else {
Log-Message "Fehler beim Bearbeiten des Logs '$logName': $_" "ERROR"
}
}
}
Log-Message "Event-Log-Bereinigung abgeschlossen: $clearedCount gelöscht, $skippedCount übersprungen, $errorCount Fehler" "SUCCESS"
}
catch {
Log-Message "Fehler in clear-event-logs: $_" "ERROR"
}
}
<#
.SYNOPSIS
Bereinigt den Windows Update Cache.
.DESCRIPTION
Stoppt den Windows Update-Dienst, löscht den Inhalt des SoftwareDistribution-Ordners
und startet den Dienst wieder.
.EXAMPLE
cleanup-windows-update
Bereinigt den Windows Update Cache.
.NOTES
Diese Funktion erfordert Administratorrechte.
#>
function cleanup-windows-update {
[CmdletBinding()]
param ()
try {
Log-Message "Starte cleanup-windows-update"
# Prüfe Größe des Update-Caches vor der Bereinigung
$updateCachePath = "C:\Windows\SoftwareDistribution"
$sizeBefore = 0
if (Test-Path -Path $updateCachePath) {
$sizeBefore = (Get-ChildItem -Path $updateCachePath -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB
Log-Message "Windows Update Cache-Größe vor Bereinigung: $([math]::Round($sizeBefore, 2)) MB" "INFO"
}
# Stoppe den Windows Update-Dienst
Log-Message "Stoppe Windows Update-Dienst" "INFO"
Stop-Service -Name wuauserv -Force -ErrorAction Stop
# Lösche den Inhalt des SoftwareDistribution-Ordners
if (Test-Path -Path $updateCachePath) {
Remove-Item -LiteralPath "$updateCachePath\*" -Recurse -Force -ErrorAction SilentlyContinue
Log-Message "Windows Update Cache-Dateien gelöscht" "SUCCESS"
}
# Starte den Windows Update-Dienst wieder
Log-Message "Starte Windows Update-Dienst" "INFO"
Start-Service -Name wuauserv -ErrorAction Stop
# Prüfe Größe nach der Bereinigung
$sizeAfter = 0
if (Test-Path -Path $updateCachePath) {
$sizeAfter = (Get-ChildItem -Path $updateCachePath -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB
$savedSpace = $sizeBefore - $sizeAfter
Log-Message "Windows Update Cache-Größe nach Bereinigung: $([math]::Round($sizeAfter, 2)) MB (gespart: $([math]::Round($savedSpace, 2)) MB)" "SUCCESS"
}
Log-Message "Windows Update Cache erfolgreich bereinigt" "SUCCESS"
}
catch {
Log-Message "Fehler in cleanup-windows-update: $_" "ERROR"
# Versuche, den Windows Update-Dienst zu starten, falls er gestoppt wurde
try {
Start-Service -Name wuauserv -ErrorAction SilentlyContinue
}
catch {
Log-Message "Konnte Windows Update-Dienst nicht neu starten: $_" "ERROR"
}
}
}
<#
.SYNOPSIS
Aktualisiert Gruppenrichtlinien.
.DESCRIPTION
Führt eine Aktualisierung der Gruppenrichtlinien auf dem Computer durch.
.EXAMPLE
update-group-policy
Aktualisiert Gruppenrichtlinien mit Force-Option.
.NOTES
Diese Funktion erfordert Administratorrechte.
#>
function update-group-policy {
[CmdletBinding()]
param ()
try {
Log-Message "Starte update-group-policy"
# Führe gpupdate mit Force-Option aus
$process = Start-Process -FilePath "gpupdate.exe" -ArgumentList "/force" -Wait -PassThru -NoNewWindow
# Prüfe Exit-Code
if ($process.ExitCode -eq 0) {
Log-Message "Gruppenrichtlinien erfolgreich aktualisiert" "SUCCESS"
}
else {
Log-Message "Gruppenrichtlinien-Update abgeschlossen mit Exit-Code $($process.ExitCode)" "WARNING"
}
}
catch {
Log-Message "Fehler in update-group-policy: $_" "ERROR"
}
}
<#
.SYNOPSIS
Bereinigt alte Benutzerprofile.
.DESCRIPTION
Identifiziert und löscht Benutzerprofile, die seit einer bestimmten Zeit
nicht mehr verwendet wurden.
.EXAMPLE
cleanup-user-profiles
Bereinigt Benutzerprofile, die seit mehr als 6000 Tagen nicht verwendet wurden.
.NOTES
Diese Funktion erfordert Administratorrechte.
Systemprofile und aktive Profile werden nicht gelöscht.
#>
function cleanup-user-profiles {
[CmdletBinding()]
param ()
try {
Log-Message "Starte cleanup-user-profiles"
# Berechne das Datum für die Filterung (6000 Tage zurück)
$cutoffDate = (Get-Date).AddDays(-6000)
$cutoffFileTime = $cutoffDate.ToFileTime()
Log-Message "Suche nach Benutzerprofilen, die seit $($cutoffDate.ToString('yyyy-MM-dd')) nicht verwendet wurden" "INFO"
# Hole alle Benutzerprofile
$allProfiles = Get-WmiObject -Class Win32_UserProfile -ErrorAction Stop
# Filtere die zu löschenden Profile
$profilesToDelete = $allProfiles | Where-Object {
# Überspringe Systemprofile, spezielle Profile und das aktuell angemeldete Profil
$_.Special -eq $false -and
$_.Loaded -eq $false -and
$_.LastUseTime -ne $null -and
$_.LastUseTime -lt $cutoffFileTime
}
if ($profilesToDelete.Count -eq 0) {
Log-Message "Keine alten Benutzerprofile gefunden, die gelöscht werden können" "INFO"
return
}
# Zeige die zu löschenden Profile an
foreach ($profile in $profilesToDelete) {
$lastUseDate = [DateTime]::FromFileTime($profile.LastUseTime)
Log-Message "Wird gelöscht: $($profile.LocalPath) (Zuletzt verwendet: $($lastUseDate.ToString('yyyy-MM-dd')))" "INFO"
# Lösche das Profil
try {
Remove-WmiObject -InputObject $profile -ErrorAction Stop
Log-Message "Benutzerprofil gelöscht: $($profile.LocalPath)" "SUCCESS"
}
catch {
Log-Message "Fehler beim Löschen des Profils $($profile.LocalPath): $_" "ERROR"
}
}
Log-Message "Alte Benutzerprofile erfolgreich bereinigt" "SUCCESS"
}
catch {
Log-Message "Fehler in cleanup-user-profiles: $_" "ERROR"
}
}
<#
.SYNOPSIS
Bereinigt temporäre Dateien.
.DESCRIPTION
Löscht temporäre Dateien aus dem Windows-Temp-Verzeichnis und dem
Temp-Verzeichnis des aktuellen Benutzers.
.EXAMPLE
cleanup-temp-files
Bereinigt alle temporären Dateien.
.NOTES
Einige Dateien können möglicherweise nicht gelöscht werden, wenn sie
von Prozessen verwendet werden.
#>
function cleanup-temp-files {
[CmdletBinding()]
param ()
try {
Log-Message "Starte cleanup-temp-files"
# Definiere zu bereinigende Verzeichnisse
$tempFolders = @(
@{
Path = "C:\Windows\Temp";
Name = "Windows-Temp";
},
@{
Path = $env:TEMP;
Name = "Benutzer-Temp";
}
)
foreach ($folder in $tempFolders) {
if (Test-Path -Path $folder.Path) {
# Ermittle Größe vor der Bereinigung
$sizeBefore = (Get-ChildItem -Path $folder.Path -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB
Log-Message "$($folder.Name)-Verzeichnis Größe vor Bereinigung: $([math]::Round($sizeBefore, 2)) MB" "INFO"
# Versuche, alle Dateien zu löschen
$errorCount = 0
Get-ChildItem -Path "$($folder.Path)\*" -Recurse -Force -ErrorAction SilentlyContinue |
ForEach-Object {
try {
Remove-Item -LiteralPath $_.FullName -Recurse -Force -ErrorAction SilentlyContinue
}
catch {
$errorCount++
}
}
# Ermittle Größe nach der Bereinigung
$sizeAfter = (Get-ChildItem -Path $folder.Path -Recurse -Force -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB
$savedSpace = $sizeBefore - $sizeAfter
Log-Message "$($folder.Name)-Verzeichnis Größe nach Bereinigung: $([math]::Round($sizeAfter, 2)) MB (gespart: $([math]::Round($savedSpace, 2)) MB)" "SUCCESS"
if ($errorCount -gt 0) {
Log-Message "Konnte $errorCount Dateien in $($folder.Name) nicht löschen (möglicherweise in Verwendung)" "WARNING"
}
}
else {
Log-Message "$($folder.Name)-Verzeichnis nicht gefunden" "WARNING"
}
}
Log-Message "Temporäre Dateien erfolgreich bereinigt" "SUCCESS"
}
catch {
Log-Message "Fehler in cleanup-temp-files: $_" "ERROR"
}
}
<#
.SYNOPSIS
Bereinigt den DNS-Client-Cache.
.DESCRIPTION
Löscht alle DNS-Einträge aus dem lokalen DNS-Client-Cache.
.EXAMPLE
cleanup-dns-cache
Bereinigt den DNS-Client-Cache.
#>
function cleanup-dns-cache {
[CmdletBinding()]
param ()
try {
Log-Message "Starte cleanup-dns-cache"
# Hole DNS-Cache-Einträge vor der Bereinigung
$entriesBefore = (Get-DnsClientCache -ErrorAction SilentlyContinue).Count
Log-Message "DNS-Cache enthält $entriesBefore Einträge vor der Bereinigung" "INFO"
# Bereinige den DNS-Cache
Clear-DnsClientCache -ErrorAction Stop
# Bestätige die Bereinigung
$entriesAfter = (Get-DnsClientCache -ErrorAction SilentlyContinue).Count
Log-Message "DNS-Cache erfolgreich bereinigt ($entriesBefore Einträge entfernt)" "SUCCESS"
}
catch {
Log-Message "Fehler in cleanup-dns-cache: $_" "ERROR"
}
}
<#
.SYNOPSIS
Hauptfunktion zur Systembereinigung.
.DESCRIPTION
Führt alle definierten Bereinigungsfunktionen nacheinander aus.
Protokolliert den Fortschritt und die Ergebnisse.
.EXAMPLE
cleanup
Führt eine vollständige Systembereinigung durch.
.NOTES
Diese Funktion erfordert Administratorrechte.
#>
function cleanup {
[CmdletBinding()]
param ()
try {
$startTime = Get-Date
Log-Message "===== STARTE SYSTEMBEREINIGUNG =====" "INFO"
Log-Message "Startzeit: $($startTime.ToString('yyyy-MM-dd HH:mm:ss'))" "INFO"
# Führe alle Bereinigungsfunktionen nacheinander aus
Log-Message "Führe cleanup-mgr aus..." "INFO"
cleanup-mgr
Log-Message "Führe delete-folders aus..." "INFO"
delete-folders
Log-Message "Führe clear-event-logs aus..." "INFO"
clear-event-logs
Log-Message "Führe cleanup-windows-update aus..." "INFO"
cleanup-windows-update
Log-Message "Führe update-group-policy aus..." "INFO"
update-group-policy
# Benutzerprofile-Bereinigung ist standardmäßig deaktiviert (potenziell gefährlich)
# Entfernen Sie den Kommentar, um diese Funktion zu aktivieren
# Log-Message "Führe cleanup-user-profiles aus..." "INFO"
# cleanup-user-profiles
Log-Message "Führe cleanup-temp-files aus..." "INFO"
cleanup-temp-files
Log-Message "Führe cleanup-dns-cache aus..." "INFO"
cleanup-dns-cache
# Berechne Gesamtdauer
$endTime = Get-Date
$duration = $endTime - $startTime
Log-Message "===== SYSTEMBEREINIGUNG ABGESCHLOSSEN =====" "SUCCESS"
Log-Message "Endzeit: $($endTime.ToString('yyyy-MM-dd HH:mm:ss'))" "INFO"
Log-Message "Gesamtdauer: $($duration.Hours) Stunden, $($duration.Minutes) Minuten, $($duration.Seconds) Sekunden" "INFO"
}
catch {
Log-Message "Kritischer Fehler in cleanup: $_" "ERROR"
}
}
# Prüfe, ob das Skript als Administrator ausgeführt wird
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Host "Dieses Skript erfordert Administratorrechte. Bitte starten Sie PowerShell als Administrator." -ForegroundColor Red
exit
}
# Ausführung der Systembereinigung
cleanup