private/Save-WinPEDriverPackageVMwareArm64.ps1

#Requires -PSEdition Core

function Save-WinPEDriverPackageVMwareArm64 {
    <#
    .SYNOPSIS
        Downloads and prepares VMware drivers for arm64
 
    .DESCRIPTION
        Downloads the VMware Tools Windows arm64 ISO to the OSDeployCore download cache.
        VMware does not publish a checksum for this ISO, so the download is not hash verified.
 
        Unless DownloadOnly is specified, the function expands the ISO into a temporary
        directory and copies only the svga, vmusbmouse, and vmxnet3 directories into the
        managed driver library. When the destination is incomplete or contains other content,
        all existing destination content is removed before it is rebuilt. The temporary
        directory is removed in a finally block.
 
    .PARAMETER DriverPackage
        Specifies the arm64 OSDeployWinPEDriver.Package object to download. The object supplies
        the package name, version, architecture, URIs, and filename.
 
    .PARAMETER Force
        Downloads the ISO again even when a cached file is available.
 
    .PARAMETER DownloadOnly
        Returns after downloading the ISO without expanding or replacing managed driver content.
 
    .EXAMPLE
        PS> $package = Get-WinPEDriverPackageCore | Where-Object { $_.Name -Match 'VMware' -and $_.Architecture -eq 'arm64' } | Select-Object -First 1; Save-WinPEDriverPackageVMwareArm64 -DriverPackage $package
 
        Downloads the first arm64 VMware package and prepares its supported driver directories.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.IO.FileInfo. Returns the downloaded ISO, or no object when the download fails.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-08-28
 
        Rebuilding recursively removes existing content from the package destination.
 
    .LINK
        Save-WinPEDriverPackageCore
    #>

    [CmdletBinding()]
    [OutputType([System.IO.FileInfo])]
    param (
        [Parameter(Mandatory)]
        [PSTypeName('OSDeployWinPEDriver.Package')]
        [PSCustomObject]$DriverPackage,

        [Parameter()]
        [switch]$Force,

        [Parameter()]
        [switch]$DownloadOnly
    )

    $package     = $DriverPackage
    $idPrefix    = ($package.Name -split '-')[0]
    $downloadDir = Join-Path $script:OSDeployCoreDownloadsPath $idPrefix
    $targetPath  = Join-Path $downloadDir $package.FileName
    $driverDir   = Join-Path $script:OSDeployBootAssetsPath "winpedrivers-$($package.Architecture)" |
                   Join-Path -ChildPath "$($package.Name)-$($package.Version)"
    $allowedDriverDirectories = @('svga', 'vmusbmouse', 'vmxnet3')

    # VMware ISOs do not have published checksums — download without hash verification
    $downloadedFile = Invoke-WinPEDriverPackageDownload `
        -Uri             $package.DownloadUri `
        -DestinationPath $targetPath `
        -SearchUri       $package.UpdateUri `
        -Force:$Force

    if (-not $downloadedFile) {
        return
    }

    if ($DownloadOnly) {
        return $downloadedFile
    }

    $targetDirectories = @(
        foreach ($directoryName in $allowedDriverDirectories) {
            Join-Path $driverDir $directoryName
        }
    )
    $targetFiles = Get-ChildItem -Path $targetDirectories -Recurse -File -ErrorAction SilentlyContinue
    $extraContent = if (Test-Path -Path $driverDir -PathType Container) {
        Get-ChildItem -Path $driverDir -Force -ErrorAction SilentlyContinue |
            Where-Object { $_.Name -notin $allowedDriverDirectories } |
            Select-Object -First 1
    }

    if ((-not $targetFiles) -or $extraContent) {
        $tempExpandDir = Join-Path ([System.IO.Path]::GetTempPath()) ("WinPEDrivers-VMwareARM64-{0}" -f [guid]::NewGuid().Guid)

        try {
            if (Test-Path -Path $driverDir -PathType Container) {
                Write-Verbose "[$($MyInvocation.MyCommand.Name)] Resetting '$driverDir' before copying VMware arm64 driver directories."
                Get-ChildItem -Path $driverDir -Force -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force
            }
            else {
                New-Item -ItemType Directory -Path $driverDir -Force | Out-Null
            }

            New-Item -ItemType Directory -Path $tempExpandDir -Force | Out-Null
            Write-HostDateTimeDarkGray -Message "Expand: $targetPath"
        Write-HostDateTimeDarkGray -Message "Output: $driverDir"
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Expanding '$($package.FileName)' to temporary directory '$tempExpandDir'"
            Expand-WinPEDriverPackageIso -Path $targetPath -DestinationPath $tempExpandDir | Out-Null

            $sourceDirectories = @(
                foreach ($directoryName in $allowedDriverDirectories) {
                    $sourceDirectory = Join-Path $tempExpandDir $directoryName
                    if (Test-Path -Path $sourceDirectory -PathType Container) {
                        Get-Item -Path $sourceDirectory
                    }
                }
            )

            if (-not $sourceDirectories) {
                throw "Expected VMware arm64 driver directories were not found in '$tempExpandDir'."
            }

            foreach ($sourceDirectory in $sourceDirectories) {
                $destinationDirectory = Join-Path $driverDir $sourceDirectory.Name
                Write-Verbose "[$($MyInvocation.MyCommand.Name)] Copying VMware arm64 driver directory '$($sourceDirectory.FullName)' to '$destinationDirectory'"
                Copy-Item -Path $sourceDirectory.FullName -Destination $driverDir -Recurse -Force
            }
        }
        finally {
            if (Test-Path -Path $tempExpandDir -PathType Container) {
                Write-Verbose "[$($MyInvocation.MyCommand.Name)] Removing temporary directory '$tempExpandDir'"
                Remove-Item -Path $tempExpandDir -Recurse -Force
            }
        }
    }
    else {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] '$driverDir' already contains VMware arm64 driver directories. Skipping expansion."
    }

    $downloadedFile
}