diverse Änderungen

This commit is contained in:
2026-05-15 16:05:34 +02:00
parent d7e1eb33ba
commit 54fd0c3347
7 changed files with 1412 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
param(
[string]$BackupRoot = "H:\Windows-Neuaufsetzen-Backup",
[string]$UserProfilePath = $env:USERPROFILE,
[switch]$IncludeOllama
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Invoke-RobocopyBackup {
param(
[string]$Source,
[string]$Destination,
[string]$LogName
)
if (-not (Test-Path $Source)) {
Write-Host "SKIP missing source: $Source"
return
}
New-Item -ItemType Directory -Force -Path $Destination | Out-Null
$LogDir = Join-Path $BackupRoot "12_Exportierte_Listen"
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
$LogPath = Join-Path $LogDir $LogName
Write-Host "COPY $Source"
Write-Host " -> $Destination"
robocopy $Source $Destination /E /COPY:DAT /DCOPY:DAT /R:2 /W:2 /XJ /TEE /LOG:$LogPath
$ExitCode = $LASTEXITCODE
if ($ExitCode -gt 7) {
throw "Robocopy failed with exit code $ExitCode for source: $Source"
}
}
if (-not (Test-Path $BackupRoot)) {
throw "BackupRoot does not exist: $BackupRoot"
}
if (-not (Test-Path $UserProfilePath)) {
throw "UserProfilePath does not exist: $UserProfilePath"
}
$CurrentUserJobs = @(
@{ Source = Join-Path $UserProfilePath "Desktop"; Destination = Join-Path $BackupRoot "01_Desktop"; Log = "backup_current_desktop.log" },
@{ Source = Join-Path $UserProfilePath "Documents"; Destination = Join-Path $BackupRoot "02_Dokumente"; Log = "backup_current_documents.log" },
@{ Source = Join-Path $UserProfilePath "Pictures"; Destination = Join-Path $BackupRoot "03_Bilder"; Log = "backup_current_pictures.log" },
@{ Source = Join-Path $UserProfilePath "Videos"; Destination = Join-Path $BackupRoot "04_Videos"; Log = "backup_current_videos.log" },
@{ Source = Join-Path $UserProfilePath "Downloads"; Destination = Join-Path $BackupRoot "05_Downloads_wichtig\_current_downloads_all"; Log = "backup_current_downloads.log" },
@{ Source = Join-Path $UserProfilePath "Music"; Destination = Join-Path $BackupRoot "15_Musik"; Log = "backup_current_music.log" },
@{ Source = Join-Path $UserProfilePath ".ssh"; Destination = Join-Path $BackupRoot "09_Programme_Settings_Lizenzen\ssh"; Log = "backup_current_ssh.log" }
)
foreach ($Job in $CurrentUserJobs) {
Invoke-RobocopyBackup -Source $Job.Source -Destination $Job.Destination -LogName $Job.Log
}
$GitConfig = Join-Path $UserProfilePath ".gitconfig"
if (Test-Path $GitConfig) {
$GitDest = Join-Path $BackupRoot "09_Programme_Settings_Lizenzen\git"
New-Item -ItemType Directory -Force -Path $GitDest | Out-Null
Copy-Item -LiteralPath $GitConfig -Destination (Join-Path $GitDest ".gitconfig") -Force
}
$OldUserRoot = "D:\Users\Baerchen"
$OldUserJobs = @(
@{ Source = Join-Path $OldUserRoot "Desktop"; Destination = Join-Path $BackupRoot "99_Unsortiert_von_D_F_G\D_Users_Baerchen\Desktop"; Log = "backup_old_baerchen_desktop.log" },
@{ Source = Join-Path $OldUserRoot "Documents"; Destination = Join-Path $BackupRoot "99_Unsortiert_von_D_F_G\D_Users_Baerchen\Documents"; Log = "backup_old_baerchen_documents.log" },
@{ Source = Join-Path $OldUserRoot "Pictures"; Destination = Join-Path $BackupRoot "99_Unsortiert_von_D_F_G\D_Users_Baerchen\Pictures"; Log = "backup_old_baerchen_pictures.log" },
@{ Source = Join-Path $OldUserRoot "Videos"; Destination = Join-Path $BackupRoot "99_Unsortiert_von_D_F_G\D_Users_Baerchen\Videos"; Log = "backup_old_baerchen_videos.log" },
@{ Source = Join-Path $OldUserRoot "Downloads"; Destination = Join-Path $BackupRoot "99_Unsortiert_von_D_F_G\D_Users_Baerchen\Downloads"; Log = "backup_old_baerchen_downloads.log" },
@{ Source = Join-Path $OldUserRoot "Music"; Destination = Join-Path $BackupRoot "99_Unsortiert_von_D_F_G\D_Users_Baerchen\Music"; Log = "backup_old_baerchen_music.log" }
)
foreach ($Job in $OldUserJobs) {
Invoke-RobocopyBackup -Source $Job.Source -Destination $Job.Destination -LogName $Job.Log
}
$ExtraJobs = @(
@{ Source = "F:\BMW Leasing"; Destination = Join-Path $BackupRoot "07_Banking_Finanzen\BMW Leasing"; Log = "backup_f_bmw_leasing.log" },
@{ Source = "F:\Marina Handy 2025"; Destination = Join-Path $BackupRoot "03_Bilder\Marina Handy 2025"; Log = "backup_f_marina_handy_2025.log" },
@{ Source = "F:\Marina Handy Backup"; Destination = Join-Path $BackupRoot "03_Bilder\Marina Handy Backup"; Log = "backup_f_marina_handy_backup.log" },
@{ Source = "G:\Gitea_Clone"; Destination = Join-Path $BackupRoot "06_Projekte\Gitea_Clone"; Log = "backup_g_gitea_clone.log" },
@{ Source = "G:\open-webui"; Destination = Join-Path $BackupRoot "09_Programme_Settings_Lizenzen\open-webui"; Log = "backup_g_open_webui.log" },
@{ Source = "G:\Treiber"; Destination = Join-Path $BackupRoot "13_Treiber_Windows\G_Treiber"; Log = "backup_g_treiber.log" }
)
if ($IncludeOllama) {
$ExtraJobs += @{ Source = "G:\Ollama"; Destination = Join-Path $BackupRoot "09_Programme_Settings_Lizenzen\Ollama"; Log = "backup_g_ollama.log" }
}
foreach ($Job in $ExtraJobs) {
Invoke-RobocopyBackup -Source $Job.Source -Destination $Job.Destination -LogName $Job.Log
}
Write-Host ""
Write-Host "Known-data backup finished."
Write-Host "Backup root: $BackupRoot"
Write-Host "Logs: $BackupRoot\12_Exportierte_Listen"
if (-not $IncludeOllama) {
Write-Host "Note: G:\Ollama was not copied. Re-run with -IncludeOllama if you want to keep local models too."
}
@@ -0,0 +1,69 @@
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$ExpectedDiskNumber = 0
$ExpectedFriendlyName = "INTEL SSDSC2BW180A3L"
$ExpectedSerialNumber = "CVCV3105053K180EGN"
$MinSizeGB = 160
$MaxSizeGB = 180
function Assert-Admin {
$Identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = [Security.Principal.WindowsPrincipal]::new($Identity)
if (-not $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
throw "Dieses Skript muss in PowerShell als Administrator ausgefuehrt werden."
}
}
Assert-Admin
$Disk = Get-Disk -Number $ExpectedDiskNumber
$SizeGB = [math]::Round($Disk.Size / 1GB, 2)
Write-Host "Zieldatentraeger:"
$Disk | Select-Object Number, FriendlyName, SerialNumber, HealthStatus, OperationalStatus, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB,2)}}, PartitionStyle | Format-Table -AutoSize
Write-Host "Aktuelle Partitionen auf Datentraeger ${ExpectedDiskNumber}:"
Get-Partition -DiskNumber $ExpectedDiskNumber | Sort-Object PartitionNumber | Select-Object DiskNumber, PartitionNumber, DriveLetter, Type, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB,3)}} | Format-Table -AutoSize
if ($Disk.FriendlyName -ne $ExpectedFriendlyName) {
throw "Abbruch: FriendlyName passt nicht. Erwartet '$ExpectedFriendlyName', gefunden '$($Disk.FriendlyName)'."
}
if ($Disk.SerialNumber -ne $ExpectedSerialNumber) {
throw "Abbruch: SerialNumber passt nicht. Erwartet '$ExpectedSerialNumber', gefunden '$($Disk.SerialNumber)'."
}
if ($SizeGB -lt $MinSizeGB -or $SizeGB -gt $MaxSizeGB) {
throw "Abbruch: Groesse passt nicht. Erwartet ca. 167 GB, gefunden $SizeGB GB."
}
$SystemPartitions = Get-Partition -DiskNumber $ExpectedDiskNumber | Where-Object {
$_.IsBoot -or $_.IsSystem -or $_.IsActive
}
if ($SystemPartitions) {
throw "Abbruch: Datentraeger $ExpectedDiskNumber enthaelt Boot/System/Aktiv-Partitionen."
}
Write-Host ""
Write-Host "WARNUNG: Datentraeger 0 wird jetzt komplett geleert."
Write-Host "Das betrifft die alte Windows-SSD mit aktuell D: und Recovery-Partitionen."
Write-Host "Andere Datentraeger werden nicht angefasst."
Write-Host ""
$Confirmation = Read-Host "Tippe exakt LEEREN um fortzufahren"
if ($Confirmation -ne "LEEREN") {
throw "Abbruch: Bestaetigung wurde nicht eingegeben."
}
Clear-Disk -Number $ExpectedDiskNumber -RemoveData -RemoveOEM -Confirm:$false
Write-Host ""
Write-Host "Datentraeger $ExpectedDiskNumber wurde geleert."
Write-Host "Ergebnis:"
Get-Disk -Number $ExpectedDiskNumber | Select-Object Number, FriendlyName, HealthStatus, OperationalStatus, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB,2)}}, PartitionStyle | Format-Table -AutoSize
Get-Partition -DiskNumber $ExpectedDiskNumber -ErrorAction SilentlyContinue | Format-Table -AutoSize
Write-Host ""
Write-Host "Naechster Schritt: Vom Windows-USB-Stick booten und Windows auf den nicht zugeordneten Speicher von Datentraeger 0 installieren."
@@ -0,0 +1,34 @@
param(
[string]$BackupRoot = "H:\Windows-Neuaufsetzen-Backup",
[switch]$ImportWingetList
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
throw "winget is not available. Install or update App Installer from Microsoft Store first."
}
Write-Host "Installing UniGetUI..."
winget install --exact --id Devolutions.UniGetUI --source winget --accept-package-agreements --accept-source-agreements
$WingetExport = Join-Path $BackupRoot "12_Exportierte_Listen\winget-export.json"
if ($ImportWingetList) {
if (-not (Test-Path $WingetExport)) {
throw "WinGet export file not found: $WingetExport"
}
Write-Host "Importing WinGet package list..."
Write-Host "Source: $WingetExport"
winget import --import-file $WingetExport --accept-package-agreements --accept-source-agreements
} else {
Write-Host ""
Write-Host "UniGetUI installed."
Write-Host "WinGet export is available here:"
Write-Host " $WingetExport"
Write-Host ""
Write-Host "Review the list before importing. To import later, run:"
Write-Host " .\postinstall-unigetui.ps1 -ImportWingetList"
}
@@ -0,0 +1,139 @@
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."