private/Get-WimIndexCache.ps1
|
#Requires -Version 7.4 function Get-WimIndexCache { <# .SYNOPSIS Gets cached Windows image index metadata .DESCRIPTION Computes the SHA256 hash of an image and reads its image index metadata from $Script:OSDeployCorePath\cache\hashes\<hash>.json when present. On a cache miss, the function queries every index with Get-WindowsImage, selects serializable metadata, and writes a UTF-8 JSON cache file before returning the rows. The cache directory is created when absent. .PARAMETER ImagePath Specifies the WIM or ESD image to hash and query. Get-FileHash, Get-Item, and Get-WindowsImage enforce path validity. .EXAMPLE PS> Get-WimIndexCache -ImagePath 'D:\sources\install.wim' Returns cached index metadata for install.wim or queries the image and creates its hash-keyed JSON cache file. .INPUTS None. This function does not accept pipeline input. .OUTPUTS System.Management.Automation.PSCustomObject. Returns zero or more image index rows containing the selected image identity, size, architecture, version, edition, language, count, timestamp, boot, path, and logging properties. Cached rows are deserialized JSON objects; fresh rows are selected PowerShell objects. .NOTES Author: David Segura Company: Recast Software Version: 0.1.0 Date: 2026-08-28 Dependencies: PowerShell Modules: Dism DotNet Classes: System.Management.Automation.PSCustomObject #> [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$ImagePath ) $CacheDirectory = Join-Path $Script:OSDeployCorePath 'cache' 'hashes' if (-not (Test-Path -Path $CacheDirectory)) { New-Item -ItemType Directory -Path $CacheDirectory -Force | Out-Null } # Compute SHA256 hash of the image file Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Computing Hash SHA256: $ImagePath" $FileHash = (Get-FileHash -Path $ImagePath -Algorithm SHA256).Hash Write-Verbose "[$($MyInvocation.MyCommand.Name)] Hash SHA256: $FileHash" $CacheFilePath = Join-Path $CacheDirectory "$FileHash.json" # Check for cache hit if (Test-Path -Path $CacheFilePath) { Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Using cached image index for $FileHash" $CacheData = Get-Content -Path $CacheFilePath -Raw | ConvertFrom-Json return $CacheData.Images } # Cache miss - query DISM for all indexes Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Querying image indexes (no cache): $ImagePath" $IndexList = Get-WindowsImage -ImagePath $ImagePath $ImageDetails = foreach ($Entry in $IndexList) { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Querying index $($Entry.ImageIndex): $($Entry.ImageName)" Get-WindowsImage -ImagePath $Entry.ImagePath -Index $Entry.ImageIndex } # Build cache object $FileInfo = Get-Item -Path $ImagePath $CacheObject = [ordered]@{ Hash = $FileHash ImagePath = $ImagePath FileSize = $FileInfo.Length CachedTime = (Get-Date).ToString('o') ImageCount = @($ImageDetails).Count Images = @($ImageDetails | ForEach-Object { # Select only serializable properties $_ | Select-Object -Property ImagePath, ImageIndex, ImageName, ImageDescription, ImageSize, WIMBoot, Architecture, Hal, Version, SPBuild, SPLevel, EditionId, InstallationType, ProductName, ProductType, ProductSuite, Languages, DefaultLanguageIndex, DirectoryCount, FileCount, CreatedTime, ModifiedTime, MajorVersion, MinorVersion, Build, ImageBootable, SystemRoot, LogPath, ScratchDirectory, LogLevel, ImageType }) } # Save to cache $CacheObject | ConvertTo-Json -Depth 5 | Out-File -FilePath $CacheFilePath -Encoding utf8 -Force Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Cached image index: $FileHash" return $CacheObject.Images } |