private/Select-BuildOSDeployBootWinpeStartupProfiles.ps1

#Requires -PSEdition Core

function Select-BuildOSDeployBootWinpeStartupProfiles {
    <#
    .SYNOPSIS
        Selects WinpeStartup profiles for an OSDeploy Boot build
 
    .DESCRIPTION
        Enumerates WinpeStartup profile folders and legacy JSON files from the OSDeploy module, available OSDCloud and OSD module
        core\winpestartup-profiles directories, and the OSDeploy Boot-Assets
        winpestartup-profiles directory. A profile folder contains winpestartup.json.
        Discovered profiles are displayed in an Out-GridView multi-selection picker.
        Profiles with the same name in different source directories are displayed as
        separate entries.
 
        The caller uses selected profiles as build content. This function does not copy
        or modify the profiles. Canceling the picker returns no object.
 
    .EXAMPLE
        PS> Select-BuildOSDeployBootWinpeStartupProfiles
 
        Displays all discovered WinpeStartup profiles for multi-selection.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.Management.Automation.PSCustomObject[]. Returns selected objects with Name,
        FullName, and LastWriteTime properties. FullName is a profile folder path for new
        profiles and a JSON file path for legacy profiles.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-08-28
 
        Change Summary:
            - Initial version.
 
        OSDCloud and OSD profile roots are searched only when their module path commands are available.
 
    .LINK
        Build-OSDeployBoot
    #>

    [CmdletBinding()]
    param ()

    $OSDRepoPaths = @(Join-Path $Script:OSDeployModuleBase 'core' 'winpestartup-profiles')

    $osdCloudBase = if (Get-Command -Name 'Get-OSDCloudModulePath' -ErrorAction SilentlyContinue) { Get-OSDCloudModulePath }
    if ($osdCloudBase) {
        $OSDRepoPaths += Join-Path $osdCloudBase 'core' 'winpestartup-profiles'
    }

    $osdBase = if (Get-Command -Name 'Get-OSDModulePath' -ErrorAction SilentlyContinue) { Get-OSDModulePath }
    if ($osdBase) {
        $OSDRepoPaths += Join-Path $osdBase 'core' 'winpestartup-profiles'
    }

    $OSDRepoPaths += Join-Path $Script:OSDeployBootAssetsPath 'winpestartup-profiles'

    $profileItems = @()
    foreach ($OSDRepoPath in $OSDRepoPaths) {
        if (Test-Path -LiteralPath $OSDRepoPath) {
            $profileItems += Get-ChildItem -LiteralPath $OSDRepoPath -Filter '*.json' -File -ErrorAction SilentlyContinue |
                Select-Object Name, FullName, LastWriteTime | Sort-Object Name

            foreach ($profileFolder in (Get-ChildItem -LiteralPath $OSDRepoPath -Directory -ErrorAction SilentlyContinue | Sort-Object Name)) {
                $profileFilePath = Join-Path $profileFolder.FullName 'winpestartup.json'
                if (Test-Path -LiteralPath $profileFilePath -PathType Leaf) {
                    $profileFile = Get-Item -LiteralPath $profileFilePath
                    $profileItems += [pscustomobject]@{
                        Name          = $profileFolder.Name
                        FullName      = $profileFolder.FullName
                        LastWriteTime = $profileFile.LastWriteTime
                    }
                }
            }
        }
    }

    if ($profileItems -and $profileItems.Count -gt 0) {
        Write-HostDateTimeDarkGray 'Select WinpeStartup Profiles to add to this boot image (Cancel to skip)'
        $selected = $profileItems | Sort-Object Name |
            Out-GridView -PassThru -Title 'Select WinpeStartup Profiles to add to this boot image (Cancel to skip)'

        return $selected
    }

    return $null
}