Private/Repair-Win32ToolkitTestVMCheckpoint.ps1
|
function Repair-Win32ToolkitTestVMCheckpoint { <# .SYNOPSIS Configures guest AutoLogon and re-takes the warm clean-base checkpoint at a logged-in desktop — including from the half-provisioned states an interrupted New-Win32ToolkitTestVM leaves behind. .DESCRIPTION HOST-ONLY; may prompt (TUI/console use). Provisioning persists the guest credential and takes 'clean-base' only at its very END (New-Win32ToolkitTestVM), so aborting it — e.g. closing the console during the manual-prep pause — leaves the VM existing but the backend unusable: no checkpoint to revert to and no stored credential to reach the guest. This is the repair path for exactly that, so it must not REQUIRE the pieces it repairs: 1. Credential: use -Credential, else the stored one, else PROMPT (type-it-twice) for the credential the golden image was built with. A freshly typed credential is persisted ONLY after PowerShell Direct proves it against the guest (step 3) — a typo is never stored. 2. Checkpoint: revert to it when it exists (the classic login-screen fix); when it is MISSING, just ensure the VM is powered on so PowerShell Direct can reach it. 3. Wait-Win32ToolkitVMReady — heartbeat + PowerShell Direct + guest prep (same gates every other checkpoint-taking flow runs). 4. Set-Win32ToolkitGuestAutoLogon, then Confirm-Win32ToolkitGuestDesktop (reboots into AutoLogon if the guest sits at a login screen). 5. Drop ALL old checkpoints and freeze a STANDARD checkpoint at the logged-in desktop; clear the readiness cache and re-affirm the config identity keys. .PARAMETER Name VM name (default: the stored HyperVVMName, else 'win32tk-golden'). .PARAMETER CheckpointName Checkpoint to (re)create (default: the stored HyperVCheckpoint, else 'clean-base'). .PARAMETER Credential Guest local-admin credential. Default: the stored credential; if none is stored (or it was saved by a different Windows user — DPAPI), an interactive prompt asks for the one baked into the image. .OUTPUTS [bool] — $true when the checkpoint was re-taken at a desktop; $false when no desktop could be reached (log in once in the VM window, then re-run). #> [CmdletBinding()] [OutputType([bool])] param( [string]$Name = (Get-Win32ToolkitConfigValue -Name 'HyperVVMName' -Default 'win32tk-golden'), [string]$CheckpointName = (Get-Win32ToolkitConfigValue -Name 'HyperVCheckpoint' -Default 'clean-base'), [pscredential]$Credential ) # Only the VM itself is mandatory — without one there is nothing to repair. $vm = Get-VM -Name $Name -ErrorAction SilentlyContinue if (-not $vm) { throw "Test VM '$Name' does not exist — provision it first (New-Win32ToolkitTestVM / the TUI's Hyper-V test VM screen)." } # 1. Resolve the credential. Persisting a hand-typed one is DEFERRED until PowerShell Direct has # accepted it, so the store can never end up holding a password the guest does not have. $persistCredential = $false if (-not $Credential) { $Credential = Get-Win32ToolkitGuestCredential if (-not $Credential) { Write-Host 'No guest credential is stored — an interrupted provision (or one saved by a different Windows user) causes this.' -ForegroundColor Yellow $Credential = Get-Win32ToolkitGuestCredentialInteractive -Message "Enter the SAME guest admin credential VM '$Name' was built with — it is verified against the guest before being saved." $persistCredential = $true } } # 2. Revert when the checkpoint exists; when it is missing (the other half of a broken provision), # there is nothing to revert to — just make sure the VM is running. Start-VM also resumes a # Saved/Paused VM. if (Get-VMCheckpoint -VMName $Name -Name $CheckpointName -ErrorAction SilentlyContinue) { Reset-Win32ToolkitTestVM -Name $Name -CheckpointName $CheckpointName } elseif ($vm.State -ne 'Running') { Write-Host "No '$CheckpointName' checkpoint to revert to — booting the VM instead..." -ForegroundColor Yellow Clear-Win32ToolkitHyperVStateCache Start-VM -Name $Name -ErrorAction Stop } # 3. Same readiness gates every checkpoint-taking flow runs (heartbeat, PS Direct proves the # credential, guest prep). A wrong typed password surfaces here as a gate timeout — and is # therefore never persisted below. Wait-Win32ToolkitVMReady -VMName $Name -Credential $Credential | Out-Null if ($persistCredential) { Set-Win32ToolkitGuestCredential -Credential $Credential Clear-Win32ToolkitHyperVStateCache Write-Host '✓ Guest credential verified over PowerShell Direct and saved.' -ForegroundColor Green } # 4. AutoLogon + a real desktop (Confirm reboots into AutoLogon if the guest is at a login screen). Set-Win32ToolkitGuestAutoLogon -VMName $Name -Credential $Credential if (-not (Confirm-Win32ToolkitGuestDesktop -VMName $Name -Credential $Credential)) { return $false } # 5. Freeze the logged-in desktop as the new clean base and make the readiness banner see it. Get-VMCheckpoint -VMName $Name -ErrorAction SilentlyContinue | Remove-VMCheckpoint -ErrorAction SilentlyContinue Set-VM -Name $Name -CheckpointType Standard Checkpoint-VM -VMName $Name -SnapshotName $CheckpointName Clear-Win32ToolkitHyperVStateCache Set-Win32ToolkitConfigValue -Name 'HyperVVMName' -Value $Name Set-Win32ToolkitConfigValue -Name 'HyperVCheckpoint' -Value $CheckpointName Write-Host "✓ '$CheckpointName' checkpoint re-taken at a logged-in desktop." -ForegroundColor Green return $true } |