private/WinPEDrivers/CloudWinPEDriver/Get-CloudWinPEDriver.ps1

#Requires -PSEdition Core

function Get-CloudWinPEDriver {
    <#
    .SYNOPSIS
        Returns WinPE driver package information from the module config and driver catalog.
 
    .DESCRIPTION
        Internal helper for Update-OSDeployWinPEDrivers and Save-CloudWinPEDriver. It combines static
        configuration from winpedrivers.json with dynamic version data from the user-scoped
        catalog at $env:ProgramData\OSDeployCore\cache\config\winpedrivers.json to produce
        OSDeployWinPEDriver.Package objects.
 
        Source behaviour is determined by properties present in winpedrivers.json:
          Dynamic — source has UpdateUri; ExpandCommand and Architecture come from
                     winpedrivers.json; all other metadata comes from the catalog.
          Static — source has DownloadUri; all metadata is read directly from
                     winpedrivers.json. No catalog lookup needed.
 
    .PARAMETER Name
        One or more source names to return. Tab-completion covers all active sources.
        When omitted, all active sources are returned.
 
    .PARAMETER SkipCatalogRefresh
        Internal switch used by Update-OSDeployWinPEDrivers when the catalog has already been refreshed.
 
    .OUTPUTS
        [PSCustomObject] with PSTypeName 'OSDeployWinPEDriver.Package'
 
    .NOTES
        Author: David Segura
        Version: 0.1.0
    #>

    [CmdletBinding()]
    [OutputType('OSDeployWinPEDriver.Package')]
    param (
        [Parameter(Position = 0)]
        [ArgumentCompleter({
            param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
            $global:OSDeployModule.WinPEDrivers.PSObject.Properties |
                Where-Object { ($_.Value.UpdateUri -or $_.Value.DownloadUri) -and -not $_.Value.Disabled -and $_.Name -like "$wordToComplete*" } |
                ForEach-Object { [System.Management.Automation.CompletionResult]::new($_.Name) }
        })]
        [string[]]$Name,

        [Parameter()]
        [switch]$SkipCatalogRefresh
    )

    begin {
        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Starting"

        $catalog = $null
    }

    process {
        if (-not $Name) {
            $Name = $global:OSDeployModule.WinPEDrivers.PSObject.Properties |
                Where-Object { ($_.Value.UpdateUri -or $_.Value.DownloadUri) -and -not $_.Value.Disabled } |
                Select-Object -ExpandProperty Name
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No -Name specified — resolving all active sources: $($Name -join ', ')"
        }
        else {
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Processing requested source(s): $($Name -join ', ')"
        }

        $dynamicTargets = @(
            foreach ($sourceName in $Name) {
                $source = $global:OSDeployModule.WinPEDrivers.$sourceName
                if ($source -and $source.UpdateUri) {
                    $sourceName
                }
            }
        )

        if ($dynamicTargets -and -not $SkipCatalogRefresh) {
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Refreshing dynamic catalog entries: $($dynamicTargets -join ', ')"
            Update-OSDeployWinPEDriversCatalog -Name $dynamicTargets | Out-Null
        }
        elseif ($dynamicTargets) {
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] SkipCatalogRefresh specified — assuming catalog entries are current for: $($dynamicTargets -join ', ')"
        }
        else {
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No dynamic sources requested — catalog refresh skipped"
        }

        $hasDynamic = $global:OSDeployModule.WinPEDrivers.PSObject.Properties |
            Where-Object { $_.Value.UpdateUri }

        if ($hasDynamic) {
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Loading catalog from '$Script:OSDeployWinPEDriversUserConfig'"
            if (Test-Path -Path $Script:OSDeployWinPEDriversUserConfig) {
                $catalog = Get-Content -Path $Script:OSDeployWinPEDriversUserConfig -Raw | ConvertFrom-Json
                Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Catalog loaded successfully"
            }
            else {
                Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Catalog not found at '$Script:OSDeployWinPEDriversUserConfig'. Run Update-OSDeployWinPEDrivers to generate it."
            }
        }
        else {
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No Dynamic sources — catalog load skipped"
        }

        foreach ($n in $Name) {
            $sourceData = $global:OSDeployModule.WinPEDrivers.$n
            if (-not $sourceData) {
                Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$n' not found in winpedrivers.json"
                continue
            }

            if ($sourceData.Disabled) {
                Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$n' — Disabled, skipping"
                continue
            }

            $arch = $sourceData.Architecture
            Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$n' — Architecture='$arch'"

            if ($sourceData.DownloadUri) {
                Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$n' — Reading metadata from winpedrivers.json (Static)"
                [PSCustomObject]@{
                    PSTypeName    = 'OSDeployWinPEDriver.Package'
                    Name          = $n
                    Architecture  = $arch
                    UpdateUri    = $null
                    ExpandCommand = $sourceData.ExpandCommand
                    ReadmeUri     = $null
                    Id            = $n
                    PackageId     = $sourceData.PackageId
                    Version       = $null
                    ReleaseDate   = $null
                    FileName      = $sourceData.FileName
                    FileSizeMB    = $sourceData.FileSizeMB
                    DownloadUri   = $sourceData.DownloadUri
                    Checksums     = [PSCustomObject]@{}
                }
            }
            elseif ($sourceData.UpdateUri) {
                if (-not $catalog) {
                    Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No catalog available for Dynamic source '$n'. Run Update-OSDeployWinPEDrivers."
                    continue
                }

                Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$n' — Looking up catalog entry"
                $catalogEntry = $catalog.Sources.$n

                if (-not $catalogEntry) {
                    Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No catalog entry for '$n'. Run Update-OSDeployWinPEDrivers."
                    continue
                }

                Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$n' — Catalog entry found: PackageId='$($catalogEntry.PackageId)' Version='$($catalogEntry.Version)' ReleaseDate='$($catalogEntry.ReleaseDate)'"
                [PSCustomObject]@{
                    PSTypeName    = 'OSDeployWinPEDriver.Package'
                    Name          = $n
                    Architecture  = $arch
                    UpdateUri    = $sourceData.UpdateUri
                    ExpandCommand = $sourceData.ExpandCommand
                    ReadmeUri     = $catalogEntry.ReadmeUri
                    Id            = $n
                    PackageId     = $catalogEntry.PackageId
                    Version       = $catalogEntry.Version
                    ReleaseDate   = $catalogEntry.ReleaseDate
                    FileName      = $catalogEntry.FileName
                    FileSizeMB    = $catalogEntry.FileSizeMB
                    DownloadUri   = $catalogEntry.DownloadUri
                    Checksums     = $catalogEntry.Checksums
                }
            }
        }
    }

    end {
        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Finished"
    }
}