Files
homelab-infra/ops/windows-reinstall/prepare-backup-inventory.ps1
2026-05-15 16:05:34 +02:00

140 lines
3.9 KiB
PowerShell

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."