param( [string]$BackupRoot = "H:\Windows-Neuaufsetzen-Backup", [string]$UserProfilePath = $env:USERPROFILE ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" function New-BackupFolder { param([string]$Name) $Path = Join-Path $BackupRoot $Name New-Item -ItemType Directory -Force -Path $Path | Out-Null return $Path } function Export-CsvSafe { param( [Parameter(ValueFromPipeline = $true)]$InputObject, [string]$Path ) begin { $Items = @() } process { $Items += $InputObject } end { $Items | Export-Csv -Path $Path -NoTypeInformation -Encoding UTF8 } } if (-not (Test-Path $UserProfilePath)) { throw "UserProfilePath does not exist: $UserProfilePath" } New-Item -ItemType Directory -Force -Path $BackupRoot | Out-Null $Folders = @( "01_Desktop", "02_Dokumente", "03_Bilder", "04_Videos", "05_Downloads_wichtig", "06_Projekte", "07_Banking_Finanzen", "08_Browser_Lesezeichen_Profile", "09_Programme_Settings_Lizenzen", "10_Games_Savegames", "11_Homelab_NAS_Doku", "12_Exportierte_Listen", "13_Treiber_Windows", "14_Screenshots", "15_Musik", "99_Unsortiert_von_D_F_G" ) $Folders | ForEach-Object { New-BackupFolder $_ | Out-Null } $ExportDir = Join-Path $BackupRoot "12_Exportierte_Listen" Get-ItemProperty ` HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, ` HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.PSObject.Properties.Name -contains "DisplayName" -and -not [string]::IsNullOrWhiteSpace($_.DisplayName) } | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate, InstallLocation | Sort-Object DisplayName | Export-CsvSafe -Path (Join-Path $ExportDir "installierte_programme.csv") if (Get-Command winget -ErrorAction SilentlyContinue) { winget list | Out-File -FilePath (Join-Path $ExportDir "winget-list.txt") -Encoding UTF8 } Get-Volume | Sort-Object DriveLetter | Select-Object DriveLetter, FileSystemLabel, FileSystem, Size, SizeRemaining, HealthStatus | Export-CsvSafe -Path (Join-Path $ExportDir "laufwerke.csv") Get-Disk | Select-Object Number, FriendlyName, SerialNumber, HealthStatus, OperationalStatus, Size, PartitionStyle | Export-CsvSafe -Path (Join-Path $ExportDir "datentraeger.csv") Get-Partition | Select-Object DiskNumber, PartitionNumber, DriveLetter, Type, Size, GptType | Sort-Object DiskNumber, PartitionNumber | Export-CsvSafe -Path (Join-Path $ExportDir "partitionen.csv") try { wmic path softwarelicensingservice get OA3xOriginalProductKey | Out-File -FilePath (Join-Path $ExportDir "windows_oem_key.txt") -Encoding UTF8 } catch { "Could not read OEM key: $($_.Exception.Message)" | Out-File -FilePath (Join-Path $ExportDir "windows_oem_key.txt") -Encoding UTF8 } if (Get-Command manage-bde -ErrorAction SilentlyContinue) { manage-bde -status | Out-File -FilePath (Join-Path $ExportDir "bitlocker_status.txt") -Encoding UTF8 } if (Get-Command wsl -ErrorAction SilentlyContinue) { wsl --list --verbose | Out-File -FilePath (Join-Path $ExportDir "wsl-distros.txt") -Encoding UTF8 } $KnownUserPaths = @( "Desktop", "Documents", "Pictures", "Videos", "Downloads", "Music", ".ssh", ".gitconfig" ) $KnownUserPaths | ForEach-Object { $Path = Join-Path $UserProfilePath $_ [pscustomobject]@{ Name = $_ Path = $Path Exists = Test-Path $Path LastWriteTime = if (Test-Path $Path) { (Get-Item $Path -Force).LastWriteTime } else { $null } } } | Export-CsvSafe -Path (Join-Path $ExportDir "benutzerpfade.csv") Write-Host "" Write-Host "Backup preparation inventory created:" Write-Host " $BackupRoot" Write-Host "" Write-Host "Next manual steps:" Write-Host " 1. Save screenshots into: $BackupRoot\14_Screenshots" Write-Host " 2. Review CSV files in: $ExportDir" Write-Host " 3. Start data backup only after confirming H: is the correct external drive."