diverse Änderungen
This commit is contained in:
@@ -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."
|
||||
Reference in New Issue
Block a user