private/BootMedia/Steps/Select-OSDeployCoreBuildProfile.ps1
|
#Requires -PSEdition Core function Select-OSDeployCoreBuildProfile { <# .SYNOPSIS Displays build profiles in an Out-GridView picker. .DESCRIPTION Scans the Repository\build-profiles directory for saved JSON profiles and presents them in an Out-GridView for interactive selection. Each entry shows key profile properties (Architecture, Languages, TimeZone, etc.) read from the JSON file. The returned object has a FullName property with the full path to the selected JSON file. .OUTPUTS PSCustomObject with FullName property, or $null if no selection is made. .NOTES Author: David Segura Company: Recast Software Change Summary: - Initial version. - Updated output path from builds to boot-media; moved build-profiles under Repository. - Added JSON content display in Out-GridView showing Architecture, Languages, and other profile properties. #> [CmdletBinding()] param () $profilePath = Join-Path $script:OSDeployCoreRepositoryPath 'build-profiles' if (-not (Test-Path -Path $profilePath)) { return $null } $results = @(Get-ChildItem -Path $profilePath -Filter '*.json' -File -ErrorAction SilentlyContinue) if ($results.Count -gt 0) { Write-OSDeployCoreProgress 'Select a Build Profile (Cancel to create a new one)' $profileObjects = foreach ($file in $results) { try { $json = Get-Content -LiteralPath $file.FullName -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop } catch { $json = $null } $driverCount = if ($json.WinPEDriver) { @($json.WinPEDriver).Count } else { 0 } [PSCustomObject]@{ Name = $file.BaseName LastModified = $file.LastWriteTime Architecture = $json.Architecture Languages = ($json.Languages -join ', ') SetInputLocale = $json.SetInputLocale SetAllIntl = $json.SetAllIntl SetTimeZone = $json.SetTimeZone WinPEStartupProfile = $json.WinPEStartupProfile WinPECustomWallpaper = $json.WinPECustomWallpaper WinPEAppScript = ($json.WinPEAppScript -join ', ') WinPEScript = ($json.WinPEScript -join ', ') WinPEMediaScript = ($json.WinPEMediaScript -join ', ') WinPEDrivers = $driverCount FullName = $file.FullName } } while ($true) { $selected = $profileObjects | Out-GridView -OutputMode Single -Title 'Select a Build Profile (Cancel to create a new one)' if (-not $selected) { return $null } # Validate all path-bearing properties in the selected profile try { $profileJson = Get-Content -LiteralPath $selected.FullName -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop } catch { Write-Warning "Could not read build profile: $($selected.FullName)" Write-Warning $_.Exception.Message continue } $pathProperties = [ordered]@{ WinPEDriver = $profileJson.WinPEDriver WinPEAppScript = $profileJson.WinPEAppScript WinPEScript = $profileJson.WinPEScript WinPEMediaScript = $profileJson.WinPEMediaScript WinPEStartupProfile = $profileJson.WinPEStartupProfile WinPECustomWallpaper = $profileJson.WinPECustomWallpaper } # Expand tokens to absolute paths before Test-Path validation $expandedProperties = [ordered]@{} foreach ($prop in $pathProperties.Keys) { $expandedProperties[$prop] = Expand-OSDeployBuildProfileToken $pathProperties[$prop] } $invalidPaths = foreach ($prop in $expandedProperties.Keys) { foreach ($entry in @($expandedProperties[$prop])) { if ($entry -and -not (Test-Path -LiteralPath $entry)) { [PSCustomObject]@{ Property = $prop; Path = $entry } } } } if ($invalidPaths) { Write-Warning "Build profile has path errors: $($selected.FullName)" foreach ($bad in $invalidPaths) { Write-Warning "[$($bad.Property)] Path not found: $($bad.Path)" } Write-Warning 'Fix the build profile and try again, or cancel to create a new one.' continue } # Auto-migrate: re-tokenize paths and rewrite the file if anything changed $tokenizedProperties = [ordered]@{} foreach ($prop in $pathProperties.Keys) { $tokenizedProperties[$prop] = ConvertTo-OSDeployBuildProfileToken $pathProperties[$prop] } $needsMigration = $false foreach ($prop in $pathProperties.Keys) { $original = @($pathProperties[$prop]) | Where-Object { $_ } $tokenized = @($tokenizedProperties[$prop]) | Where-Object { $_ } if (($original -join '|') -ine ($tokenized -join '|')) { $needsMigration = $true break } } if ($needsMigration) { Write-Verbose "Migrating build profile to use module path tokens: $($selected.FullName)" $updatedProfile = [ordered]@{ Architecture = $profileJson.Architecture WinPEDriver = $tokenizedProperties['WinPEDriver'] WinPEAppScript = $tokenizedProperties['WinPEAppScript'] WinPEScript = $tokenizedProperties['WinPEScript'] WinPEMediaScript = $tokenizedProperties['WinPEMediaScript'] WinPEStartupProfile = if ($tokenizedProperties['WinPEStartupProfile']) { $tokenizedProperties['WinPEStartupProfile'][0] } else { $null } WinPECustomWallpaper = if ($tokenizedProperties['WinPECustomWallpaper']) { $tokenizedProperties['WinPECustomWallpaper'][0] } else { $null } Languages = $profileJson.Languages SetAllIntl = $profileJson.SetAllIntl SetInputLocale = $profileJson.SetInputLocale SetTimeZone = $profileJson.SetTimeZone } try { $updatedProfile | ConvertTo-Json -Depth 5 -WarningAction SilentlyContinue | Out-File -LiteralPath $selected.FullName -Encoding utf8 -Force } catch { Write-Warning "Could not migrate build profile tokens: $($_.Exception.Message)" } } return $selected } } return $null } |