private/Step-BuildBootInstallWinPEAppZip.ps1

#Requires -PSEdition Core

function Step-BuildBootInstallWinPEAppZip {
    <#
    .SYNOPSIS
        Downloads, caches, and injects 7-Zip into the mounted WinPE image
 
    .DESCRIPTION
        Removes loose files and noncurrent version directories from the 7-Zip cache,
        then creates or reuses the configured version directory. It downloads 7zr.exe
        and the 7-Zip extra archive when absent, using curl.exe when available and
        Invoke-WebRequest otherwise, and extracts the archive with cached 7zr.exe.
 
        For amd64 or arm64 builds with a matching extracted directory, the function
        copies that directory's files into Windows\System32 in the mounted image and
        appends 7zip to global BuildMedia.InstalledApps.
 
    .EXAMPLE
        PS> Step-BuildBootInstallWinPEAppZip
 
        Refreshes the configured 7-Zip cache and injects the selected architecture.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        None. Native download output is silent and extraction output is suppressed.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 0.1.0
        Date: 2026-08-28
 
        Requires global BuildMedia with Architecture, MountPath, and InstalledApps
        properties; global OSDeployModule.BootImage.winpeapps.sevenzip; and script
        OSDeployCorePath. Requires network access for cache misses. Destructively
        removes obsolete cache content and modifies the mounted image and global state.
    #>

    [CmdletBinding()]
    param ()

    $Architecture = $global:BuildMedia.Architecture
    $MountPath = $global:BuildMedia.MountPath
    $WinPEAppsPath = Join-Path $Script:OSDeployCorePath 'cache' 'winpe-apps'
    $zipConfig = $global:OSDeployModule.BootImage.winpeapps.sevenzip

    $zipVersion = $zipConfig.version
    $CacheZipRoot = Join-Path $WinPEAppsPath '7zip'
    $CacheZip = Join-Path $CacheZipRoot $zipVersion

    # Cleanup old versions
    if (Test-Path -Path $CacheZipRoot) {
        Get-ChildItem -Path $CacheZipRoot -File -ErrorAction SilentlyContinue | Remove-Item -Force
        Get-ChildItem -Path $CacheZipRoot -Directory -ErrorAction SilentlyContinue |
            Where-Object { $_.Name -ne $zipVersion } |
            Remove-Item -Recurse -Force
    }

    if (Test-Path -Path $CacheZip) {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Using 7-Zip cache: $CacheZip"
    }
    else {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Creating 7-Zip cache: $CacheZip"
        New-Item -Path $CacheZip -ItemType Directory -Force | Out-Null
    }

    # Download 7zr.exe standalone
    if (-not (Test-Path -Path "$CacheZip\7zr.exe")) {
        $downloadUrl = $zipConfig.standalone
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Downloading 7zr.exe"
        $downloadPath = Join-Path $CacheZip '7zr.exe'
        if (Get-Command 'curl.exe' -ErrorAction SilentlyContinue) {
            & curl.exe --silent --location --retry 5 --continue-at - --output $downloadPath $downloadUrl
        }
        else {
            Invoke-WebRequest -UseBasicParsing -Uri $downloadUrl -OutFile $downloadPath
        }
    }

    # Download and extract 7z extra archive
    if (-not (Test-Path -Path "$CacheZip\7za")) {
        $downloadUrl = $zipConfig.extra
        $extraFileName = Split-Path $downloadUrl -Leaf
        $downloadPath = Join-Path $CacheZip $extraFileName
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Downloading 7-Zip extra: $extraFileName"
        if (Get-Command 'curl.exe' -ErrorAction SilentlyContinue) {
            & curl.exe --silent --location --retry 5 --continue-at - --output $downloadPath $downloadUrl
        }
        else {
            Invoke-WebRequest -UseBasicParsing -Uri $downloadUrl -OutFile $downloadPath
        }
        $null = & "$CacheZip\7zr.exe" x "$downloadPath" -o"$CacheZip\7za" -y
    }

    # Copy to WinPE
    if ($Architecture -eq 'amd64') {
        if (Test-Path "$CacheZip\7za\x64") {
            Write-HostDateTimeDarkGray 'Injecting 7-Zip (x64) into WinPE'
            Copy-Item -Path "$CacheZip\7za\x64\*" -Destination "$MountPath\Windows\System32" -Recurse -Force
            $global:BuildMedia.InstalledApps += '7zip'
        }
    }
    if ($Architecture -eq 'arm64') {
        if (Test-Path "$CacheZip\7za\arm64") {
            Write-HostDateTimeDarkGray 'Injecting 7-Zip (arm64) into WinPE'
            Copy-Item -Path "$CacheZip\7za\arm64\*" -Destination "$MountPath\Windows\System32" -Recurse -Force
            $global:BuildMedia.InstalledApps += '7zip'
        }
    }
}