private/Get-OSDeployCoreWindowsRE.ps1

#Requires -PSEdition Core

function Get-OSDeployCoreWindowsRE {
    <#
    .SYNOPSIS
        Gets imported Windows RE sources from OSDeployCore
 
    .DESCRIPTION
        Recursively reads properties.json files beneath the OSDeployCore
        cache\windows-re directory, resolves each source's winre.wim, and returns flattened
        metadata for valid sources. Unreadable metadata and entries without an image are
        skipped with warnings. Results are sorted by architecture and then by version
        descending. No objects are returned when the source directory or valid entries are
        absent.
 
    .PARAMETER Architecture
        Filters results to amd64 or arm64. When omitted, all architectures found in the
        imported metadata are returned.
 
    .EXAMPLE
        PS> Get-OSDeployCoreWindowsRE -Architecture 'amd64'
 
        Returns imported amd64 Windows RE sources with their flattened image metadata.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.Management.Automation.PSCustomObject. Returns zero or more objects with Type,
        Id, Name, CreatedTime, ModifiedTime, InstallationType, Version, Architecture,
        Languages, image metadata, Path, ImagePath, and ImageIndex properties.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 0.1.0
        Date: 2026-08-28
 
        Dependencies:
          DotNet Classes: System.Management.Automation.PSCustomObject
    #>

    [CmdletBinding()]
    param (
        [ValidateSet('amd64', 'arm64')]
        [System.String]
        $Architecture
    )

    $sourcePath = Join-Path $Script:OSDeployCorePath 'cache' 'windows-re'

    if (-not (Test-Path -Path $sourcePath)) {
        Write-Warning "[$(Get-Date -Format s)] WinRE sources directory not found: $sourcePath"
        return $null
    }

    # Search all subdirectories for properties.json files
    $propertiesFiles = Get-ChildItem -Path $sourcePath -Filter 'properties.json' -Recurse -File -ErrorAction SilentlyContinue

    if (@($propertiesFiles).Count -eq 0) {
        Write-Warning "[$(Get-Date -Format s)] No imported WinRE sources found in $sourcePath"
        Write-Warning "[$(Get-Date -Format s)] Mount a Windows 25H2 ISO and run Import-OSDeployCoreOS to import WinRE."
        return $null
    }

    $results = foreach ($propertiesFile in $propertiesFiles) {
        try {
            $props = Get-Content -Path $propertiesFile.FullName -Raw | ConvertFrom-Json
        }
        catch {
            Write-Warning "[$(Get-Date -Format s)] Could not read $($propertiesFile.FullName)"
            continue
        }

        $itemDir = $propertiesFile.Directory.FullName
        $itemName = if ($props.Name) { $props.Name } else { $propertiesFile.Directory.Name }
        $itemArch = if ($props.Architecture) { $props.Architecture } else { 'unknown' }

        # Resolve ImagePath from properties or discover winre.wim
        $itemImagePath = if ($props.ImagePath -and (Test-Path -Path $props.ImagePath)) {
            $props.ImagePath
        }
        elseif (Test-Path (Join-Path $itemDir '.wim' 'winre.wim')) {
            Join-Path $itemDir '.wim' 'winre.wim'
        }
        elseif (Test-Path (Join-Path $itemDir 'winre.wim')) {
            Join-Path $itemDir 'winre.wim'
        }
        else {
            Write-Warning "[$(Get-Date -Format s)] No winre.wim found for $itemName in $itemDir"
            continue
        }

        # Flatten properties.json fields into the output object for GridView display
        [PSCustomObject][ordered]@{
            Type             = if ($props.Type) { $props.Type } else { 'WinRE' }
            Id               = if ($props.Id) { $props.Id } else { $itemName }
            Name             = $itemName
            CreatedTime      = $props.CreatedTime
            ModifiedTime     = $props.ModifiedTime
            InstallationType = $props.InstallationType
            Version          = $props.Version
            Architecture     = $itemArch
            Languages        = if ($props.Languages) { $props.Languages -join ',' } else { '' }
            ImageSize        = $props.ImageSize
            DirectoryCount   = $props.DirectoryCount
            FileCount        = $props.FileCount
            ImageName        = $props.ImageName
            OSImageName      = $props.OSImageName
            OSEditionId      = $props.OSEditionId
            OSVersion        = $props.OSVersion
            OSCreatedTime    = $props.OSCreatedTime
            OSModifiedTime   = $props.OSModifiedTime
            Path             = $itemDir
            ImagePath        = $itemImagePath
            ImageIndex       = if ($props.ImageIndex) { $props.ImageIndex } else { 1 }
        }
    }

    if ($Architecture -and $results) {
        $results = $results | Where-Object { $_.Architecture -eq $Architecture }
    }

    $results |
        Sort-Object -Property Architecture |
        Sort-Object -Property { [version]$_.Version } -Descending
}