private/BootMedia/Steps/Step-BootImageAppSysinternals.ps1

#Requires -PSEdition Core

function Step-BootImageAppSysinternals {
    <#
    .SYNOPSIS
        Downloads, caches, and injects Sysinternals tools into the mounted WinPE image.
 
    .NOTES
        Author: David Segura
        Version: 0.1.0
    #>

    [CmdletBinding()]
    param ()

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

    if (-not (Test-Path -Path $CacheDir)) {
        Write-OSDeployCoreProgress "Creating Sysinternals cache: $CacheDir"
        New-Item -Path $CacheDir -ItemType Directory -Force | Out-Null
    }
    else {
        Write-OSDeployCoreProgress "Using Sysinternals cache: $CacheDir"
    }

    foreach ($tool in $sysinternals.PSObject.Properties) {
        $toolName   = $tool.Name
        $toolConfig = $tool.Value

        # Select arch-appropriate URL; skip tool entirely if absent/empty for this arch
        $DownloadUri = $toolConfig.$Architecture
        if ([string]::IsNullOrEmpty($DownloadUri)) {
            Write-OSDeployCoreProgress "Skipping Sysinternals $toolName (no $Architecture URL)"
            continue
        }

        $CachedFile = Join-Path $CacheDir (Split-Path -Leaf $DownloadUri)

        if (-not (Test-Path -Path $CachedFile)) {
            Write-OSDeployCoreProgress "Downloading Sysinternals $toolName ($Architecture): $DownloadUri"
            try {
                if (Get-Command 'curl.exe' -ErrorAction SilentlyContinue) {
                    & curl.exe --silent --location --output $CachedFile $DownloadUri
                }
                else {
                    Invoke-WebRequest -UseBasicParsing -Uri $DownloadUri -OutFile $CachedFile
                }
            }
            catch {
                Write-Warning "Failed to download Sysinternals $toolName ($Architecture): $_"
                continue
            }
        }

        if (-not (Test-Path -Path $CachedFile)) {
            Write-Warning "Sysinternals $toolName binary not found at $CachedFile"
            continue
        }

        $Destination = Join-Path $MountPath "Windows\System32\$($toolConfig.destination)"
        Write-OSDeployCoreProgress "Injecting $($toolConfig.destination) into WinPE"
        Copy-Item -Path $CachedFile -Destination $Destination -Force
        $global:BuildMedia.InstalledApps += $toolName
    }
}