Files
awoooi/scripts/reboot-recovery/windows99-vmx-source-locator.ps1
Your Name 6f65764feb
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m11s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
fix(reboot): add windows99 vmx source locator
2026-07-03 12:22:03 +08:00

137 lines
4.8 KiB
PowerShell

param(
[ValidateSet("Check")]
[string]$Mode = "Check",
[string]$TargetAlias = "111",
[string[]]$ExpectedVmxPaths = @(
"D:\Documents\Virtual Machines\192.168.0.111_Ubuntu_64-bit\192.168.0.111_Ubuntu_64-bit.vmx"
),
[string[]]$DiscoveryRoot = @(
"D:\Documents\Virtual Machines",
"D:\Downloads",
"D:\VMs",
"E:\VMs",
"C:\VMs",
"C:\Users\Public\Documents\Virtual Machines"
),
[int]$MaxCandidateCount = 20
)
$ErrorActionPreference = "Stop"
if ($MaxCandidateCount -lt 1) {
$MaxCandidateCount = 20
}
function Get-StringFingerprint {
param([string]$Value)
$sha = [System.Security.Cryptography.SHA256]::Create()
try {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($Value.ToLowerInvariant())
return (($sha.ComputeHash($bytes) | ForEach-Object { $_.ToString("x2") }) -join "")
} finally {
$sha.Dispose()
}
}
function Write-BoolLine {
param(
[string]$Name,
[bool]$Value
)
Write-Output "$Name=$([int]$Value)"
}
$normalizedExpected = @(
$ExpectedVmxPaths |
Where-Object { $_ -and $_.Trim() } |
ForEach-Object { $_.Trim() } |
Select-Object -Unique
)
$normalizedRoots = @(
$DiscoveryRoot |
Where-Object { $_ -and $_.Trim() } |
ForEach-Object { $_.Trim() } |
Select-Object -Unique
)
$expectedPresentCount = 0
$expectedIndex = 0
foreach ($path in $normalizedExpected) {
$expectedIndex += 1
$present = Test-Path -LiteralPath $path
if ($present) {
$expectedPresentCount += 1
}
Write-Output "EXPECTED_VMX alias=$TargetAlias index=$expectedIndex present=$([int]$present) fingerprint=$(Get-StringFingerprint -Value $path)"
}
$rootPresentCount = 0
$rootIndex = 0
$candidateFingerprints = New-Object System.Collections.Generic.List[string]
$aliasPattern = "(^|[\\._\-\s])$([regex]::Escape($TargetAlias))([\\._\-\s]|$)"
foreach ($root in $normalizedRoots) {
$rootIndex += 1
$rootPresent = Test-Path -LiteralPath $root
if ($rootPresent) {
$rootPresentCount += 1
}
Write-Output "DISCOVERY_ROOT index=$rootIndex present=$([int]$rootPresent) fingerprint=$(Get-StringFingerprint -Value $root)"
if (-not $rootPresent) {
continue
}
try {
$matches = Get-ChildItem -LiteralPath $root -Recurse -File -Filter "*.vmx" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -match $aliasPattern } |
Select-Object -First $MaxCandidateCount
foreach ($match in @($matches)) {
if ($candidateFingerprints.Count -ge $MaxCandidateCount) {
break
}
$candidateFingerprints.Add((Get-StringFingerprint -Value $match.FullName))
}
} catch {
Write-Output "DISCOVERY_ROOT_ERROR fingerprint=$(Get-StringFingerprint -Value $root) error_type=$($_.Exception.GetType().Name)"
}
}
$candidateFingerprintValues = @($candidateFingerprints | Select-Object -Unique)
$candidateCount = $candidateFingerprintValues.Count
$candidateStatus = "blocked_missing_expected_vmx_source_no_candidate_found"
$safeNextStep = "provide_existing_vmx_source_or_backup_path_then_rerun_locator_check_mode_no_write"
if ($expectedPresentCount -gt 0) {
$candidateStatus = "ready_expected_vmx_source_present"
$safeNextStep = "rerun_no_secret_vmware_verify_collector_and_reboot_slo_scorecard"
} elseif ($candidateCount -gt 0) {
$candidateStatus = "candidate_found_for_controlled_relink_check_mode"
$safeNextStep = "record_scoped_relink_dry_run_and_rollback_then_apply_existing_vmx_source_copy_or_link"
}
Write-Output "AWOOOI_WINDOWS99_VMX_SOURCE_LOCATOR=1"
Write-Output "schema_version=windows99_vmx_source_locator_v1"
Write-Output "MODE=$Mode"
Write-Output "target_host_alias=99"
Write-Output "target_vm_alias=$TargetAlias"
Write-Output "expected_vmx_path_count=$($normalizedExpected.Count)"
Write-Output "expected_vmx_path_present_count=$expectedPresentCount"
Write-Output "discovery_root_count=$($normalizedRoots.Count)"
Write-Output "discovery_root_present_count=$rootPresentCount"
Write-Output "candidate_source_count=$candidateCount"
Write-Output "candidate_source_fingerprint_count=$candidateCount"
Write-Output "candidate_source_fingerprints=$($candidateFingerprintValues -join ',')"
Write-Output "source_locator_status=$candidateStatus"
Write-Output "safe_next_step=$safeNextStep"
Write-Output "raw_path_output=false"
Write-Output "path_fingerprint_only=true"
Write-Output "file_content_read=false"
Write-Output "secret_value_read=false"
Write-Output "password_prompt_allowed=false"
Write-Output "remote_write_performed=false"
Write-Output "host_reboot_performed=false"
Write-Output "vm_power_change_performed=false"
Write-Output "windows_registry_apply_performed=false"
Write-Output "scheduled_task_write_performed=false"