# 01-Setup-CMM.ps1 - CMM-specific setup (runs after Shopfloor baseline) # # Installs Hexagon CMM applications from a network share using credentials # stored in the SFLD registry by SetupCredentials.ps1 (PPKG phase). # # Unlike Standard PC apps (which are pre-staged locally via preinstall.json # or pulled from Azure Blob via DSC), CMM apps live on a file share and # are installed directly from there. The share credentials come from the # PPKG's YAML config and are already in the registry by the time this # script runs. # # The share path and app list are read from site-config.json's CMM profile # when available, with hardcoded West Jefferson defaults as fallback. # # PLACEHOLDER: specific app installers (PC-DMIS, CLM License, etc.) are # not yet finalized. The framework below handles credential lookup, share # mounting, and has slots for each install step. Write-Host "=== CMM Setup ===" # --- Load site config + PC profile --- . "$PSScriptRoot\..\Shopfloor\lib\Get-PCProfile.ps1" # --- Configuration --- # Share path for Hexagon CMM installers. Read from profile config, # fall back to the known West Jefferson path. $defaultSharePath = '\\tsgwp00525.wjs.geaerospace.net\shared\dt\shopfloor\cmm\hexagon\machineapps' $sharePath = $defaultSharePath if ($pcProfile -and $pcProfile.cmmSharePath) { $sharePath = $pcProfile.cmmSharePath } elseif ($siteConfig -and $siteConfig.pcProfiles -and $siteConfig.pcProfiles.CMM -and $siteConfig.pcProfiles.CMM.cmmSharePath) { $sharePath = $siteConfig.pcProfiles.CMM.cmmSharePath } Write-Host " Share: $sharePath" # ============================================================================ # Credential lookup - reads from HKLM:\SOFTWARE\GE\SFLD\Credentials\* # Written by SetupCredentials.ps1 during the PPKG phase. We scan all # credential entries and find one whose TargetHost matches the share's # server name. # ============================================================================ function Get-SFLDCredential { param([string]$ServerName) $basePath = 'HKLM:\SOFTWARE\GE\SFLD\Credentials' if (-not (Test-Path $basePath)) { Write-Warning "SFLD credential registry not found at $basePath" return $null } $entries = Get-ChildItem -Path $basePath -ErrorAction SilentlyContinue foreach ($entry in $entries) { $props = Get-ItemProperty -Path $entry.PSPath -ErrorAction SilentlyContinue if (-not $props) { continue } $targetHost = $props.TargetHost if (-not $targetHost) { continue } # Match by hostname (with or without domain suffix) if ($targetHost -eq $ServerName -or $targetHost -like "$ServerName.*" -or $ServerName -like "$targetHost.*") { return @{ Username = $props.Username Password = $props.Password TargetHost = $targetHost KeyName = $entry.PSChildName } } } Write-Warning "No SFLD credential found for server '$ServerName'" return $null } # ============================================================================ # Mount the share # ============================================================================ # Extract server name from UNC path: \\server\share\... -> server $serverName = ($sharePath -replace '^\\\\', '') -split '\\' | Select-Object -First 1 $cred = Get-SFLDCredential -ServerName $serverName $driveLetter = 'S:' if ($cred) { Write-Host " Credential: $($cred.KeyName) (user: $($cred.Username))" } else { Write-Host " No credential found for $serverName - attempting guest/current-user access" } # Disconnect any stale mapping net use $driveLetter /delete /y 2>$null | Out-Null $mountOk = $false if ($cred -and $cred.Username -and $cred.Password) { $result = & net use $driveLetter $sharePath /user:$($cred.Username) $($cred.Password) /persistent:no 2>&1 if ($LASTEXITCODE -eq 0) { Write-Host " Mounted $sharePath as $driveLetter" $mountOk = $true } else { Write-Warning " net use failed (exit $LASTEXITCODE): $result" } } else { # Try without explicit credentials (rely on CredMan or current user) $result = & net use $driveLetter $sharePath /persistent:no 2>&1 if ($LASTEXITCODE -eq 0) { Write-Host " Mounted $sharePath as $driveLetter (no explicit creds)" $mountOk = $true } else { Write-Warning " net use failed (exit $LASTEXITCODE): $result" } } if (-not $mountOk) { Write-Warning "Cannot access $sharePath - skipping CMM app installs." Write-Host "=== CMM Setup Complete (share unavailable) ===" exit 0 } # ============================================================================ # Install apps from the share # # PLACEHOLDER: uncomment and adjust when app details are finalized. # Each block follows the pattern: # 1. Find installer on the share # 2. Run it with silent args # 3. Check exit code # 4. Log result # ============================================================================ $installRoot = $driveLetter # --- Example: CLM Tools (license manager, install first) --- # $clm = Get-ChildItem -Path $installRoot -Filter "CLM_*.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 # if ($clm) { # Write-Host "Installing CLM Tools: $($clm.Name)..." # $p = Start-Process -FilePath $clm.FullName -ArgumentList "-q -norestart" -Wait -PassThru # Write-Host " CLM Tools exit code: $($p.ExitCode)" # } else { # Write-Warning "CLM Tools installer not found (expected CLM_*.exe)" # } # --- Example: PC-DMIS 2016 --- # $pcdmis16 = Get-ChildItem -Path $installRoot -Filter "Pcdmis2016*x64.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 # if ($pcdmis16) { # Write-Host "Installing PC-DMIS 2016: $($pcdmis16.Name)..." # $p = Start-Process -FilePath $pcdmis16.FullName -ArgumentList "-q INSTALLPDFCONVERTER=0 INSTALLOFFLINEHELP=0 HEIP=0 -norestart" -Wait -PassThru # Write-Host " PC-DMIS 2016 exit code: $($p.ExitCode)" # } else { # Write-Warning "PC-DMIS 2016 installer not found" # } # --- Example: PC-DMIS 2019 R2 --- # $pcdmis19 = Get-ChildItem -Path $installRoot -Filter "Pcdmis2019*x64.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 # if ($pcdmis19) { # Write-Host "Installing PC-DMIS 2019 R2: $($pcdmis19.Name)..." # $p = Start-Process -FilePath $pcdmis19.FullName -ArgumentList "-q INSTALLPDFCONVERTER=0 INSTALLOFFLINEHELP=0 HEIP=0 -norestart" -Wait -PassThru # Write-Host " PC-DMIS 2019 exit code: $($p.ExitCode)" # } else { # Write-Warning "PC-DMIS 2019 installer not found" # } Write-Host " (no apps configured yet - uncomment install blocks when ready)" # ============================================================================ # Cleanup # ============================================================================ Write-Host "Disconnecting $driveLetter..." net use $driveLetter /delete /y 2>$null | Out-Null Write-Host "=== CMM Setup Complete ==="