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 } |