Public/Repair-DisasterRecoveryReadiness.ps1
|
function Repair-DisasterRecoveryReadiness { <# .SYNOPSIS Remediates minor DR readiness violations (e.g., disconnected ISOs, missing CBT). .DESCRIPTION Accepts the [PSCustomObject] from Test-DisasterRecoveryReadiness and safely remediates configuration issues on the source VMs that violate DR readiness protocols. .PARAMETER DRResult The validation object(s) generated by Test-DisasterRecoveryReadiness. .PARAMETER SourceServer VIServer connection to the source vCenter to execute the repairs. .EXAMPLE $results = Test-DisasterRecoveryReadiness -SourceServer $src -TargetServer $tgt ... $results | Where-Object { -not $_.DRReady } | Repair-DisasterRecoveryReadiness -SourceServer $src #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [psobject[]]$DRResult, [Parameter(Mandatory=$true)] $SourceServer ) process { $ErrorActionPreference = 'Stop' foreach ($res in $DRResult) { if (-not $res.DRReady) { Write-Verbose "Attempting automated repairs for $($res.VMName)..." try { $vmView = Get-View -Server $SourceServer -ViewType VirtualMachine -Filter @{"Name"="^$($res.VMName)$"} -Property Config.ChangeTrackingEnabled,Config.Hardware.Device,Runtime.PowerState -ErrorAction Stop if (-not $vmView) { Write-Warning "Could not retrieve VM View for $($res.VMName). Skipping." continue } # 1. Enable CBT if (-not $res.CBTEnabled -and $PSCmdlet.ShouldProcess($res.VMName, "Enable Change Block Tracking (CBT)")) { $spec = New-Object VMware.Vim.VirtualMachineConfigSpec $spec.ChangeTrackingEnabled = $true $vmView.ReconfigVM_Task($spec) | Out-Null Write-Host "[REPAIRED] Enabled CBT for $($res.VMName)" -ForegroundColor Green } # 2. Disconnect Connected ISOs if ($res.StorageBlockers -match "Connected ISO" -and $PSCmdlet.ShouldProcess($res.VMName, "Disconnect Virtual CD-ROM ISO")) { $spec = New-Object VMware.Vim.VirtualMachineConfigSpec $spec.DeviceChange = @() foreach ($dev in $vmView.Config.Hardware.Device) { if ($dev.GetType().Name -eq "VirtualCdrom" -and $dev.Connectable.Connected) { $devSpec = New-Object VMware.Vim.VirtualDeviceConfigSpec $devSpec.Operation = "edit" $devSpec.Device = $dev $devSpec.Device.Connectable.Connected = $false $devSpec.Device.Connectable.StartConnected = $false $spec.DeviceChange += $devSpec } } if ($spec.DeviceChange.Count -gt 0) { $vmView.ReconfigVM_Task($spec) | Out-Null Write-Host "[REPAIRED] Disconnected ISO from $($res.VMName)" -ForegroundColor Green } } # Hard Blockers Warning if ($res.StorageBlockers -match "Physical RDM" -or $res.StorageBlockers -match "Multi-Writer VMDK") { Write-Warning "VM $($res.VMName) has unrepairable Storage Blockers (pRDMs or Multi-Writer). Manual intervention required." } } catch { Write-Error "Failed to repair $($res.VMName): $($_.Exception.Message)" } } else { Write-Verbose "$($res.VMName) is already DR Ready. No repairs needed." } } } } |