Private/Test-Win32ToolkitHyperVReady.ps1
|
function Test-Win32ToolkitHyperVReady { <# .SYNOPSIS Returns the list of reasons the Hyper-V test backend is NOT usable (empty array = ready). .DESCRIPTION Single source of truth for "can we actually use the Hyper-V backend right now?", consumed by Get-Win32ToolkitTestBackend (to fall back to Sandbox) and by the prerequisite health screen. Checks: host elevation (PowerShell Direct needs admin), the Hyper-V PowerShell module, the configured VM + its clean checkpoint, and a stored guest credential. Each missing item yields a short human-readable reason string. See knowledge-base/designs/hyperv-backend-plan.md. .OUTPUTS [string[]] — reasons the backend is not ready; an empty array means it IS ready. #> [CmdletBinding()] [OutputType([string[]])] param( # Bypass the memoized verdict (used right after an action that could have changed readiness). [switch]$Force ) # Memoize for 60 s: a single pipeline start calls this 3-5 times (backend resolution, health screen, # per-scenario checks) and each probe costs a module scan + Get-VM. Any VM-management cmdlet clears # the cache via Clear-Win32ToolkitHyperVStateCache; the short TTL bounds staleness from actions this # process cannot see (another console deleting the VM), and the worst case is a 60 s-old verdict. if (-not $Force -and $script:HyperVReadyCache -and (((Get-Date) - $script:HyperVReadyCache.At).TotalSeconds -lt 60)) { return $script:HyperVReadyCache.Reasons } $missing = [System.Collections.Generic.List[string]]::new() if (-not (Test-Win32ToolkitElevated)) { $missing.Add('host session is not elevated (PowerShell Direct needs an Administrator)') } if (-not (Get-Module -ListAvailable -Name Hyper-V)) { # Without the module we cannot check the VM/checkpoint either. $missing.Add('Hyper-V PowerShell module is not installed') } else { $vmName = Get-Win32ToolkitConfigValue -Name 'HyperVVMName' -Default 'win32tk-golden' $checkpoint = Get-Win32ToolkitConfigValue -Name 'HyperVCheckpoint' -Default 'clean-base' $vm = Get-VM -Name $vmName -ErrorAction SilentlyContinue if (-not $vm) { $missing.Add("VM '$vmName' not found") } elseif (-not (Get-VMCheckpoint -VMName $vmName -Name $checkpoint -ErrorAction SilentlyContinue)) { $missing.Add("checkpoint '$checkpoint' not found on VM '$vmName'") } } if (-not (Get-Win32ToolkitGuestCredential)) { $missing.Add('guest credential is not configured') } $script:HyperVReadyCache = @{ Reasons = $missing.ToArray(); At = Get-Date } # No unary comma: callers wrap in @(), so returning the bare array lets an EMPTY result surface as # zero elements (ready). `, $arr` would wrap even an empty array into a 1-element array (never ready). return $missing.ToArray() } |