Files
homelab-infra/ops/windows-reinstall/repair-disk0-boot-to-new-windows.ps1
T

121 lines
4.8 KiB
PowerShell

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$TargetDiskNumber = 0
$TargetWindowsDrive = "D"
$TargetDiskFriendlyName = "INTEL SSDSC2BW180A3L"
$TargetDiskSerialNumber = "CVCV3105053K180EGN"
$EfiSizeMB = 260
$EfiLabel = "SYSTEM"
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."
}
}
function Get-FreeDriveLetter {
$Used = (Get-Volume | Where-Object DriveLetter | Select-Object -ExpandProperty DriveLetter)
foreach ($Letter in "S","T","U","V","W","X","Y","Z") {
if ($Used -notcontains $Letter) {
return $Letter
}
}
throw "Kein freier Laufwerksbuchstabe fuer die EFI-Partition gefunden."
}
Assert-Admin
$Disk = Get-Disk -Number $TargetDiskNumber
$TargetWindowsPath = "$TargetWindowsDrive`:\Windows"
$TargetWinload = "$TargetWindowsDrive`:\Windows\System32\winload.efi"
Write-Host "Aktuell gestartetes Windows:"
Write-Host " SystemDrive: $env:SystemDrive"
Write-Host " windir: $env:windir"
Write-Host ""
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 "Partitionen auf Datentraeger ${TargetDiskNumber}:"
Get-Partition -DiskNumber $TargetDiskNumber | Sort-Object PartitionNumber | Select-Object DiskNumber, PartitionNumber, DriveLetter, Type, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB,3)}}, GptType | Format-Table -AutoSize
if ($Disk.FriendlyName -ne $TargetDiskFriendlyName) {
throw "Abbruch: Datentraeger 0 ist nicht die erwartete Intel-SSD."
}
if ($Disk.SerialNumber -ne $TargetDiskSerialNumber) {
throw "Abbruch: Seriennummer von Datentraeger 0 passt nicht."
}
if (-not (Test-Path $TargetWinload)) {
throw "Abbruch: Ziel-Windows wurde nicht gefunden: $TargetWinload"
}
if ($env:SystemDrive -eq "$TargetWindowsDrive`:") {
throw "Abbruch: Du bist bereits im Ziel-Windows. Dieses Skript ist fuer den Zustand gedacht, in dem neues Windows als D: sichtbar ist."
}
$ExistingEfiOnDisk0 = Get-Partition -DiskNumber $TargetDiskNumber | Where-Object {
$_.GptType -eq "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}"
}
if ($ExistingEfiOnDisk0) {
Write-Host "EFI-Systempartition auf Datentraeger 0 existiert bereits."
$EfiPartition = $ExistingEfiOnDisk0 | Select-Object -First 1
} else {
Write-Host ""
Write-Host "Auf Datentraeger 0 existiert keine EFI-Systempartition."
Write-Host "Das Skript verkleinert $TargetWindowsDrive`: um $EfiSizeMB MB und erstellt daraus eine neue EFI-Systempartition."
Write-Host ""
$Confirmation = Read-Host "Tippe exakt EFI um fortzufahren"
if ($Confirmation -ne "EFI") {
throw "Abbruch: Bestaetigung wurde nicht eingegeben."
}
$TargetPartition = Get-Partition -DiskNumber $TargetDiskNumber | Where-Object DriveLetter -eq $TargetWindowsDrive
if (-not $TargetPartition) {
throw "Abbruch: Windows-Partition $TargetWindowsDrive`: wurde auf Datentraeger 0 nicht gefunden."
}
$Supported = Get-PartitionSupportedSize -DiskNumber $TargetDiskNumber -PartitionNumber $TargetPartition.PartitionNumber
$NewSize = $TargetPartition.Size - ($EfiSizeMB * 1MB)
if ($NewSize -lt $Supported.SizeMin) {
throw "Abbruch: Partition kann nicht um $EfiSizeMB MB verkleinert werden."
}
Resize-Partition -DiskNumber $TargetDiskNumber -PartitionNumber $TargetPartition.PartitionNumber -Size $NewSize
$EfiPartition = New-Partition -DiskNumber $TargetDiskNumber -Size ($EfiSizeMB * 1MB) -GptType "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}"
Format-Volume -Partition $EfiPartition -FileSystem FAT32 -NewFileSystemLabel $EfiLabel -Confirm:$false | Out-Null
}
$EfiLetter = Get-FreeDriveLetter
Set-Partition -DiskNumber $TargetDiskNumber -PartitionNumber $EfiPartition.PartitionNumber -NewDriveLetter $EfiLetter
$EfiDrive = "$EfiLetter`:"
Write-Host ""
Write-Host "Schreibe Bootdateien fuer $TargetWindowsPath nach $EfiDrive ..."
bcdboot "$TargetWindowsPath" /s $EfiDrive /f UEFI
if ($LASTEXITCODE -ne 0) {
throw "bcdboot ist fehlgeschlagen."
}
Write-Host ""
Write-Host "Setze Bootmenue-Timeout auf 3 Sekunden."
bcdedit /timeout 3
Write-Host ""
Write-Host "Aktuelle BCD-Eintraege:"
bcdedit /enum
Write-Host ""
Write-Host "Fertig. Naechster Schritt:"
Write-Host "1. Neustarten."
Write-Host "2. Im UEFI/BIOS Windows Boot Manager der Intel-SSD/Datentraeger 0 als erste Bootoption waehlen, falls angeboten."
Write-Host "3. Im Bootmenue den neuen Windows-11-Eintrag starten."
Write-Host "4. Wenn das neue Windows laeuft, sollte SystemDrive C: sein und der alte Windows-Datentraeger einen anderen Buchstaben haben."