private/BootMedia/WindowsOS/Get-WimIndexCache.ps1
|
#Requires -Version 7.4 function Get-WimIndexCache { <# .SYNOPSIS Returns cached or freshly-queried Windows image index data for a WIM/ESD file. .DESCRIPTION Computes the SHA256 hash of the specified image file and checks the cache directory for a matching JSON file. On cache hit, the stored image index data is returned without calling Get-WindowsImage. On cache miss, Get-WindowsImage is called for each index in the image file, the results are saved to the cache, and then returned. Cache files are stored at $Script:OSDeployCorePath\cache\{sha256}.json. .PARAMETER ImagePath The full path to the install.wim or install.esd file. .OUTPUTS [PSCustomObject[]] Array of image index detail objects (same shape as Get-WindowsImage -ImagePath -Index output). .NOTES Author: David Segura Version: 0.1.0 #> [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-OSDeployCoreProgress "Computing SHA256 hash: $ImagePath" $FileHash = (Get-FileHash -Path $ImagePath -Algorithm SHA256).Hash Write-Verbose "[$($MyInvocation.MyCommand.Name)] SHA256: $FileHash" $CacheFilePath = Join-Path $CacheDirectory "$FileHash.json" # Check for cache hit if (Test-Path -Path $CacheFilePath) { Write-OSDeployCoreProgress "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-OSDeployCoreProgress "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-OSDeployCoreProgress "Cached image index: $FileHash" return $CacheObject.Images } |