🛠️ Windows Server 2022 unter Proxmox optimieren

Wenn du öfter mal einen Windows Server 2022 unter Proxmox installierst, weißt du: Viele Dinge sind von Haus aus nicht gerade für Virtualisierung optimiert. Deshalb hab ich mir ein kleines PowerShell-Skript gebastelt, das typische Performance-Optimierungen automatisch übernimmt.
Hier zeig ich dir kurz, was das Skript alles macht – vielleicht hilft’s dir ja auch.
✅ Erkennt automatisch, ob es eine VM ist
Bevor’s losgeht, prüft das Skript, ob es in einer virtuellen Maschine läuft. Wenn nicht, gibt’s eine Warnung und du kannst entscheiden, ob du weitermachen willst. Praktisch, damit du versehentlich nicht auf einem Host rumpfuscht.
🎨 Visuelle Effekte abschalten
Alle Animationen und Eye-Candy-Effekte werden deaktiviert. Das spart RAM und CPU, was gerade bei RDP/Terminalservern oder kleinen VMs nützlich ist. Du kannst das sogar global für alle Benutzerprofile umsetzen.
⚡ Energieschema auf „Höchstleistung“
Windows neigt dazu, die Leistung automatisch zu drosseln. Das Skript stellt die Energieeinstellungen direkt auf volle Leistung – genau das, was du für produktive Server willst.
🌐 Netzwerk-Tuning für VMs
Wenn du VirtIO-Treiber nutzt, wird das Netzwerk optimiert:
- TCP-Offloading wird deaktiviert
- Receive Side Scaling wird aktiviert
Das sorgt für stabilere und schnellere Netzwerklastverteilung.
🧹 Unnötige Dienste und Apps deaktivieren
Dienste wie Telemetrie, Kartendienst und die Windows-Suche (wenn nicht nötig) werden gestoppt und deaktiviert. Auch vorinstallierte Apps wie Xbox & Co. werden entfernt – perfekt für schlanke Server-Setups.
🔄 Keine automatischen Neustarts nach Updates
Damit dich Windows nicht mitten im Betrieb einfach neu startet, wird diese Funktion deaktiviert – solange ein Benutzer angemeldet ist.
🕒 NTP-Zeitserver konfigurieren
Der Server kann sich auf Wunsch mit pool.ntp.org synchronisieren. Das sorgt für eine saubere Uhrzeit, besonders bei Proxmox-Setups, wo die Host-Zeit nicht immer zuverlässig durchgereicht wird.
🧠 Windows Defender „entschärfen“
Windows Defender wird nicht deaktiviert, aber der maximale CPU-Verbrauch beim Scannen wird begrenzt. Das bringt etwas Luft, ohne auf Schutz zu verzichten.
🔧 Core Parking deaktivieren
Standardmäßig „parkt“ Windows ungenutzte CPU-Kerne. Das Skript sorgt dafür, dass alle Kerne ständig verfügbar sind – besonders hilfreich bei schwach ausgelasteten VMs.
✂️ TRIM für SSD/Thin Storage
TRIM gibt freien Speicher an den Host zurück. Du kannst einstellen, ob TRIM aktiviert oder deaktiviert werden soll – je nachdem, ob du Proxmox mit discard=on oder z. B. VMware mit Thin-VMDK nutzt.
🧽 Visuelle Effekte global abschalten (optional)
Für Terminalserver oder besonders minimalistische Umgebungen kannst du die visuellen Effekte auch global für alle Benutzer deaktivieren. Das spart nochmal Ressourcen.
🔚 Fazit
Das Skript ist kein Hexenwerk, aber es nimmt dir ordentlich Arbeit ab – vor allem bei wiederholten VM-Installationen.
✅ Schnell, pragmatisch, anpassbar.
🔄 Ein Neustart nach dem Durchlauf wird empfohlen.
Fragen, Tipps oder eigene Erfahrungen? Lass gern einen Kommentar da! 😊
# Optimierungsskript für Windows Server 2022 auf Proxmox
# -----------------------------
# 0. Systemprüfung: Läuft dieses System in einer VM?
# -----------------------------
Write-Output "Systemprüfung: Virtuelle Umgebung erkennen..."
$computerSystem = Get-WmiObject -Class Win32_ComputerSystem
$manufacturer = $computerSystem.Manufacturer
$model = $computerSystem.Model
$biosInfo = Get-WmiObject -Class Win32_BIOS
$biosVendor = $biosInfo.Manufacturer
# Erkennungsmuster für VMs (viele Hypervisoren melden sich als Hersteller)
$vmPatterns = @("QEMU", "KVM", "Microsoft Corporation", "VMware", "VirtualBox", "Xen", "Parallels", "Red Hat")
$isVM = $false
foreach ($pattern in $vmPatterns) {
if ($manufacturer -like "*$pattern*" -or $model -like "*$pattern*" -or $biosVendor -like "*$pattern*") {
$isVM = $true
break
}
}
if (-not $isVM) {
Write-Warning "⚠️ Dieses System scheint keine virtuelle Maschine zu sein."
$proceed = Read-Host "Möchtest du das Skript trotzdem fortsetzen? (J/N)"
if ($proceed -notmatch "^[Jj]") {
Write-Output "Skript wird beendet."
exit
}
} else {
Write-Output "✅ Virtuelle Maschine erkannt: $manufacturer / $model"
}
Write-Output "Starte Optimierung des Windows Server 2022..."
# 1. Deaktiviere unnötige visuelle Effekte
Write-Output "Setze visuelle Effekte auf beste Leistung..."
$PerformanceKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects'
Set-ItemProperty -Path $PerformanceKey -Name VisualFXSetting -Value 2
# 2. Deaktiviere Windows-Tipps
Write-Output "Deaktiviere Windows Tipps..."
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SoftLandingEnabled" -Value 0 -PropertyType DWord -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-310093Enabled" -Value 0 -PropertyType DWord -Force
# 3. Energieoptionen: Höchstleistung aktivieren
Write-Output "Aktiviere Energieschema Höchstleistung..."
powercfg -setactive SCHEME_MIN
# 4. Netzwerk-Optimierungen (nur wenn VM-Treiber wie VirtIO korrekt installiert sind)
Write-Output "Aktiviere TCP Offloading Optimierungen..."
Get-NetAdapter | ForEach-Object {
Set-NetAdapterAdvancedProperty -Name $_.Name -DisplayName "Large Send Offload v2 (IPv4)" -DisplayValue "Disabled" -ErrorAction SilentlyContinue
Set-NetAdapterAdvancedProperty -Name $_.Name -DisplayName "Large Send Offload v2 (IPv6)" -DisplayValue "Disabled" -ErrorAction SilentlyContinue
Set-NetAdapterAdvancedProperty -Name $_.Name -DisplayName "Receive Side Scaling" -DisplayValue "Enabled" -ErrorAction SilentlyContinue
}
# 5. Dienste deaktivieren (vorsichtig verwenden – abhängig vom Einsatzzweck!)
Write-Output "Deaktiviere nicht benötigte Dienste..."
$ServicesToDisable = @(
"DiagTrack", # Connected User Experiences and Telemetry
"WerSvc", # Windows Error Reporting
"WSearch", # Windows Search (nicht nötig für Server mit wenigen Dateien)
"MapsBroker" # Karten Dienst
)
foreach ($svc in $ServicesToDisable) {
if (Get-Service -Name $svc -ErrorAction SilentlyContinue) {
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
Set-Service -Name $svc -StartupType Disabled
}
}
# 6. Deaktiviere automatische Neustarts nach Updates
Write-Output "Verhindere automatische Neustarts nach Updates..."
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoRebootWithLoggedOnUsers" -Value 1 -Type DWord
# 7. Aktivieren von NTP-Zeitservern (optional)
Write-Output "Konfiguriere NTP-Zeitserver..."
w32tm /config /manualpeerlist:"pool.ntp.org" /syncfromflags:manual /reliable:yes /update
Restart-Service w32time
w32tm /resync
# 8. Entferne unnötige vorinstallierte Apps (optional/minimal auf Server)
Write-Output "Entferne vorinstallierte Apps (minimal)..."
Get-AppxPackage -AllUsers | Where-Object {$_.Name -like "*Xbox*" -or $_.Name -like "*Zune*"} | Remove-AppxPackage -ErrorAction SilentlyContinue
# 9. Windows Defender – Performance-Tuning (nicht deaktivieren, aber optimieren)
Write-Output "Setze Defender Performance Einstellungen..."
Set-MpPreference -ScanAvgCPULoadFactor 30
# -----------------------------
# 10. Core Parking deaktivieren
# -----------------------------
Write-Output "Deaktiviere Core Parking (für bessere CPU-Auslastung)..."
$parkingKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\54533251-82be-4824-96c1-47b60b740d00\0cc5b647-c1df-4637-891a-dec35c318583"
Set-ItemProperty -Path $parkingKey -Name "ValueMax" -Value 0 -ErrorAction SilentlyContinue
Set-ItemProperty -Path $parkingKey -Name "ValueMin" -Value 0 -ErrorAction SilentlyContinue
# Hinweis: Nach dieser Änderung muss das Energieprofil ggf. neu aktiviert werden
powercfg -setactive SCHEME_MIN
# -----------------------------
# 11. TRIM-Konfiguration per Eingabe
# -----------------------------
Write-Output ""
Write-Output "TRIM (DisableDeleteNotify) Konfiguration"
Write-Output "----------------------------------------"
Write-Output "TRIM aktiviert Speicherfreigabe bei SSD/Thin-Storage (z.B. unter Proxmox mit discard=on)."
Write-Output "0 = TRIM aktivieren (empfohlen für Proxmox)"
Write-Output "1 = TRIM deaktivieren (z.B. bei VMware mit Thin-VMDK)"
$trimChoice = Read-Host "Bitte gewünschten Wert für DisableDeleteNotify eingeben (0 oder 1)"
if ($trimChoice -eq "0" -or $trimChoice -eq "1") {
Write-Output "Setze DisableDeleteNotify auf $trimChoice..."
fsutil behavior set DisableDeleteNotify $trimChoice
} else {
Write-Output "Ungültige Eingabe – TRIM-Einstellung wird übersprungen."
}
# -----------------------------
# 12. Visuelle Effekte und Animationen deaktivieren - aktuelle Nutzer (optional)
# -----------------------------
Write-Output ""
Write-Output "Windows-Optimierung: Visuelle Effekte deaktivieren"
Write-Output "----------------------------------------------------"
Write-Output "Diese Option deaktiviert Fensteranimationen, Schatten, Transparenz und weitere visuelle Elemente."
Write-Output "Vorteil: Geringere CPU- und RAM-Auslastung, ideal für RDP/Terminalserver oder ressourcenschonende Server-VMs."
$visualChoice = Read-Host "Möchtest du alle visuellen Effekte deaktivieren? (J/N)"
if ($visualChoice -match "^[Jj]") {
Write-Output "Deaktiviere visuelle Effekte..."
# Setzt System auf beste Leistung (alle visuellen Effekte aus)
$visualEffectsReg = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects"
Set-ItemProperty -Path $visualEffectsReg -Name "VisualFXSetting" -Value 2 -ErrorAction SilentlyContinue
# Deaktiviert einzelne visuelle Features
$visualTweaks = @{
"UserPreferencesMask" = ([byte[]](0x90,0x12,0x03,0x80,0x10,0x00,0x00,0x00)) # Beste Leistung
}
foreach ($key in $visualTweaks.Keys) {
New-Item -Path "HKCU:\Control Panel\Desktop" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name $key -Value $visualTweaks[$key]
}
# Weitere Animationen ausschalten
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "MenuShowDelay" -Value "0"
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "MouseHoverTime" -Value "0"
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "ForegroundFlashCount" -Value "0"
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "AutoEndTasks" -Value "1"
# Abschalten von AeroPeek und Taskbar-Animationen
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\DWM" -Name "EnableAeroPeek" -Value 0 -PropertyType DWord -Force
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarAnimations" -Value 0
Write-Output "Visuelle Effekte wurden abgeschaltet. Abmelden oder Neustart erforderlich, um alle Änderungen zu aktivieren."
} else {
Write-Output "Visuelle Effekte bleiben unverändert."
}
# -----------------------------
# 13. Visuelle Effekte und Animationen deaktivieren (global, optional)
# -----------------------------
Write-Output ""
Write-Output "Windows-Optimierung: Visuelle Effekte global deaktivieren"
Write-Output "-------------------------------------------------------------"
Write-Output "Diese Option deaktiviert visuelle Effekte (Animationen, Schatten, Transparenz) für alle Benutzer."
Write-Output "Empfohlen für RDP-/Terminalserver oder minimalistische VM-Setups."
$visualChoice = Read-Host "Möchtest du visuelle Effekte für alle Benutzer deaktivieren? (J/N)"
if ($visualChoice -match "^[Jj]") {
Write-Output "Deaktiviere visuelle Effekte für alle Benutzerprofile..."
$userPrefsMask = ([byte[]](0x90,0x12,0x03,0x80,0x10,0x00,0x00,0x00))
$userHives = Get-ChildItem Registry::HKEY_USERS | Where-Object {
$_.Name -notlike "*_Classes"
}
foreach ($hive in $userHives) {
$sid = $hive.PSChildName
$regBase = "Registry::HKEY_USERS\$sid"
# Alle relevanten Unterschlüssel erstellen, wenn nötig
$pathsToEnsure = @(
"$regBase\Control Panel\Desktop",
"$regBase\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects",
"$regBase\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced",
"$regBase\Software\Microsoft\Windows\DWM"
)
foreach ($path in $pathsToEnsure) {
if (-not (Test-Path $path)) {
New-Item -Path $path -Force | Out-Null
}
}
# Einstellungen setzen
Set-ItemProperty -Path "$regBase\Control Panel\Desktop" -Name "MenuShowDelay" -Value "0" -Force
Set-ItemProperty -Path "$regBase\Control Panel\Desktop" -Name "MouseHoverTime" -Value "0" -Force
Set-ItemProperty -Path "$regBase\Control Panel\Desktop" -Name "ForegroundFlashCount" -Value "0" -Force
Set-ItemProperty -Path "$regBase\Control Panel\Desktop" -Name "AutoEndTasks" -Value "1" -Force
Set-ItemProperty -Path "$regBase\Control Panel\Desktop" -Name "UserPreferencesMask" -Value $userPrefsMask -Force
Set-ItemProperty -Path "$regBase\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" -Name "VisualFXSetting" -Value 2 -Force
Set-ItemProperty -Path "$regBase\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarAnimations" -Value 0 -Force
Set-ItemProperty -Path "$regBase\Software\Microsoft\Windows\DWM" -Name "EnableAeroPeek" -Value 0 -Force
}
Write-Output "Visuelle Effekte wurden für alle Benutzerprofile (inkl. .DEFAULT) deaktiviert."
Write-Output "Ein Abmelden oder Neustart ist erforderlich, um die Änderungen wirksam zu machen."
} else {
Write-Output "Visuelle Effekte bleiben unverändert."
}
# Fertig
Write-Output "Optimierung abgeschlossen. Neustart empfohlen."