Adds a wai_backup_<PC>_<ts>.zip (robocopy /E of C:\Program Files\WAI + the x86 path) alongside the goCMM + PC-DMIS backups, indexed in cmm-backup-index.json. Captures machine/controller content beyond the per-version PC-DMIS grab. Can be multi-GB if WAI holds the full PC-DMIS 2016 install. NOTE: this only CAPTURES it. sync-cmm-backups.sh + Restore-CMM still handle only gocmm/pcdmis zips - staging/restoring the WAI zip needs those updated too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
108 lines
4.9 KiB
PowerShell
108 lines
4.9 KiB
PowerShell
<#
|
|
Backup-CMM.ps1
|
|
|
|
ONE backup for a whole CMM bay - runs both:
|
|
- Backup-goCMMSettings.ps1 (HKLM goCMM key + C:\geaofi, minus LocalProgramCopies/logs)
|
|
- Backup-PCDMISSettings.ps1 (PC-DMIS registry + data/probe/cal + interfac.dll,
|
|
every installed version; Homepage state excluded)
|
|
|
|
All zips land together in one per-CMM folder so they can be staged on PXE and
|
|
restored by CMM machine-# at imaging.
|
|
|
|
Run as ADMINISTRATOR on the live CMM. Do NOT run on DODA bays (handled separately).
|
|
|
|
Output (default): S:\2 WJ Scans Record Retention\backup\cmm\<CmmId>\
|
|
gocmm_backup_<PC>_<ts>.zip
|
|
pcdmis_backup_<PC>_<ver>_<ts>.zip (one per PC-DMIS version)
|
|
cmm-backup-index.json
|
|
If S: is not mapped/reachable, falls back to C:\Logs\CMM\cmm-backup\<CmmId>\.
|
|
|
|
Params:
|
|
-CmmId <id> e.g. CMM3 - names the folder + index. If omitted, the script
|
|
PROMPTS for it.
|
|
-OutDir <p> base output folder (default the S: record-retention path above)
|
|
#>
|
|
param(
|
|
[string]$CmmId,
|
|
[string]$OutDir = 'S:\2 WJ Scans Record Retention\backup\cmm'
|
|
)
|
|
$ErrorActionPreference = 'Continue'
|
|
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
$ts = Get-Date -Format 'yyyyMMdd-HHmmss'
|
|
|
|
# Prompt for the CMM number if not passed. It names the backup folder, so we
|
|
# need a real value - loop until non-empty.
|
|
if (-not $CmmId) {
|
|
while (-not $CmmId) {
|
|
$CmmId = (Read-Host "Enter the CMM number for this bay (e.g. CMM3)").Trim()
|
|
if (-not $CmmId) { Write-Host " CMM number is required." -ForegroundColor Yellow }
|
|
}
|
|
}
|
|
|
|
# Default OutDir is on S: (record retention). If S: is not mapped or that base
|
|
# path is unreachable, fall back to a local folder so the backup still runs -
|
|
# the operator can copy it up to S: afterward.
|
|
$fallback = 'C:\Logs\CMM\cmm-backup'
|
|
$baseRoot = Split-Path -Qualifier $OutDir -ErrorAction SilentlyContinue
|
|
if ($baseRoot -and -not (Test-Path "$baseRoot\")) {
|
|
Write-Host "WARNING: $baseRoot is not reachable (S: not mapped?). Falling back to $fallback" -ForegroundColor Yellow
|
|
$OutDir = $fallback
|
|
}
|
|
$dest = Join-Path $OutDir $CmmId
|
|
New-Item -ItemType Directory -Path $dest -Force -ErrorAction SilentlyContinue | Out-Null
|
|
$log = Join-Path $dest "cmm-backup-$ts.log"
|
|
function Log($m){ Write-Host $m; $m | Out-File -FilePath $log -Append }
|
|
|
|
Log "================ CMM backup: $CmmId on $env:COMPUTERNAME at $(Get-Date) ================"
|
|
|
|
foreach ($s in 'Backup-goCMMSettings.ps1','Backup-PCDMISSettings.ps1') {
|
|
$p = Join-Path $here $s
|
|
if (-not (Test-Path $p)) { Log "MISSING sibling script: $p - skipping"; continue }
|
|
Log "---- running $s ----"
|
|
try { & $p -OutDir $dest *>&1 | ForEach-Object { Log " $_" } }
|
|
catch { Log " ERROR in $s : $($_.Exception.Message)" }
|
|
}
|
|
|
|
# --- C:\Program Files\WAI (+ x86): whole vendor tree, captured complete.
|
|
# Holds machine/controller content beyond what the per-version PC-DMIS backup
|
|
# grabs. NOTE: can be multi-GB if WAI contains the full PC-DMIS 2016 install. ---
|
|
$waiRoots = @("$env:ProgramFiles\WAI", "${env:ProgramFiles(x86)}\WAI")
|
|
$waiPresent = @($waiRoots | Where-Object { Test-Path $_ })
|
|
if ($waiPresent.Count -gt 0) {
|
|
Log "---- capturing WAI tree (whole) ----"
|
|
$waiStage = Join-Path $env:TEMP "wai-bk-$ts"
|
|
New-Item -ItemType Directory -Path $waiStage -Force | Out-Null
|
|
foreach ($wr in $waiPresent) {
|
|
$label = if ($wr -like '*(x86)*') { 'WAI-x86' } else { 'WAI' }
|
|
robocopy $wr (Join-Path $waiStage $label) /E /R:1 /W:1 /NFL /NDL /NJH /NJS | Out-Null
|
|
Log " copied $wr -> $label"
|
|
}
|
|
$waiZip = Join-Path $dest "wai_backup_${env:COMPUTERNAME}_$ts.zip"
|
|
if (Test-Path $waiZip) { Remove-Item $waiZip -Force }
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
[System.IO.Compression.ZipFile]::CreateFromDirectory($waiStage, $waiZip)
|
|
Remove-Item $waiStage -Recurse -Force -EA SilentlyContinue
|
|
Log " WAI backup: $waiZip ($([math]::Round((Get-Item $waiZip).Length/1MB)) MB)"
|
|
} else {
|
|
Log "No C:\Program Files\WAI (or x86) - skipping WAI backup"
|
|
}
|
|
|
|
# index of what we captured
|
|
$zips = Get-ChildItem $dest -Filter '*.zip' -File -ErrorAction SilentlyContinue
|
|
[pscustomobject]@{
|
|
CmmId = $CmmId
|
|
Computer = $env:COMPUTERNAME
|
|
Timestamp = (Get-Date -Format o)
|
|
goCMM = @($zips | Where-Object { $_.Name -like 'gocmm_backup_*' } | Select-Object -Expand Name)
|
|
PCDMIS = @($zips | Where-Object { $_.Name -like 'pcdmis_backup_*' } | Select-Object -Expand Name)
|
|
WAI = @($zips | Where-Object { $_.Name -like 'wai_backup_*' } | Select-Object -Expand Name)
|
|
} | ConvertTo-Json | Out-File (Join-Path $dest 'cmm-backup-index.json') -Encoding ascii
|
|
|
|
Log "================ DONE ================"
|
|
Log "Folder: $dest"
|
|
$zips | ForEach-Object { Log (" {0} ({1} KB)" -f $_.Name, [math]::Round($_.Length/1KB)) }
|
|
Write-Host ""
|
|
Write-Host "CMM backup for $CmmId complete:" -ForegroundColor Green
|
|
Write-Host " $dest"
|
|
$zips | ForEach-Object { Write-Host " $($_.Name)" }
|