Private/steps-osd/Step-OSDCloudSaveDriverPackCacheObject.ps1

function Step-OSDCloudSaveDriverPackCacheObject {
    [CmdletBinding()]
    param (
        [Parameter()]
        $DriverPackCloudObject = $global:OSDCoreDriverPackCloudObject,

        [Parameter()]
        [string]$DownloadPath = 'C:\Windows\Temp\osdcloud-driverpack-download'
    )
    #=================================================
    # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)]"
    #=================================================
    # Honor the upstream execution mode gate.
    # This step only runs when offline media usage has already been confirmed.
    # Returning here is expected behavior in online flows and is not an error.
    if (-not ($global:RecastOSDCloud.DriverPackCacheObject)) {
        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DriverPackCloudObject was not confirmed for offline usage. Skipping this step."
        return
    }
    #=================================================
    # Is there a DriverPack Object?
    if (-not ($DriverPackCloudObject)) {
        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DriverPackCloudObject is not set"
        return
    }
    #=================================================
    # Is there a DriverPack Object FileName?
    if (-not $DriverPackCloudObject.FileName) {
        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] DriverPackCloudObject.FileName is not set"
        return
    }
    #=================================================
    # Destination settings for the local deployment workspace.
    # This is the final on-disk path expected by downstream deployment steps.
    $LocalDestinationPath = Join-Path -Path $DownloadPath -ChildPath $DriverPackCloudObject.FileName
    #=================================================
    # If the destination file already exists, this step is a no-op.
    # Downstream steps can still use the existing file.
    if (Test-Path -LiteralPath $LocalDestinationPath) {
        # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Destination already exists: $LocalDestinationPath"
        # return
    }
    #=================================================
    # Refresh cache inventory so we work with current cache state.
    # Cache can be updated by earlier steps, so do not rely on stale global data.
    $global:OSDCoreCacheContent = Get-OSDCoreCacheContent
    # Re-resolve the cache object after USB access paths have been restored.
    # The original object can contain a stale drive-letter-based FullName.
    $global:RecastOSDCloud.DriverPackCacheObject = Get-OSDCoreDriverPackCacheObject `
        -DriverPackCloudObject $DriverPackCloudObject `
        -CacheContent $global:OSDCoreCacheContent
    if (-not $global:OSDCoreCacheContent) {
        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] OSDCoreCacheContent is empty"
        return
    }
    #=================================================
    # Match the exact filename requested by the selected DriverPack metadata.
    # First match is intentional because filenames should be unique in cache.
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] FileName: $($DriverPackCloudObject.FileName)"
    $CacheDriverPack = $global:RecastOSDCloud.DriverPackCacheObject
    #=================================================
    # Stop quietly when the requested payload is not cached.
    if (-not $CacheDriverPack) {
        # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] DriverPackCloudObject is not in the OSDCoreCacheContent. OK."
        return
    }
    #=================================================
    # Ensure the cache entry points to a real file before we hash or copy.
    if (-not (Test-Path -LiteralPath $CacheDriverPack.FullName)) {
        # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Cached source file not found: $($CacheDriverPack.FullName)"
        return
    }
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] FullName: $($CacheDriverPack.FullName)"
    #=================================================
    # Validate the cached source against metadata first.
    # This prevents copying a stale or tampered cache file.
    if ($DriverPackCloudObject.HashMD5) {
        # Validate cached payload before copy so we never replicate bad content.
        $SourceFileHash = Get-FileHash -Path $CacheDriverPack.FullName -Algorithm MD5
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] DriverPack MD5: $($DriverPackCloudObject.HashMD5)"
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] OSDCoreCacheContent MD5: $($SourceFileHash.Hash)"
        if ($SourceFileHash.Hash -ne $DriverPackCloudObject.HashMD5) {
            # Hash mismatch means the source cannot be trusted; skip copy.
            Write-Host -ForegroundColor DarkYellow "[$(Get-Date -format s)] OSDCoreCacheContent MD5 is not valid: $($CacheDriverPack.FullName)"
            return
        }
    }
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] DriverPackCloudObject is in OSDCoreCacheContent. OK."
    $global:RecastOSDCloud.DriverPackCacheObject = $true
    #=================================================
    # Variables
    $LogPath = "C:\Windows\Temp\osdcloud-logs"
    $Manufacturer = $DriverPackCloudObject.Manufacturer
    $ScriptsPath = "C:\Windows\Setup\Scripts"
    $SetupCompleteCmd = "$ScriptsPath\SetupComplete.cmd"
    $SetupSpecializeCmd = "C:\Windows\Temp\osdcloud\SetupSpecialize.cmd"
    $Url = $DriverPackCloudObject.Url
    #=================================================
    # Create destination directory if needed
    # Directory creation is idempotent and safe to call repeatedly.
    $ItemParams = @{
        ErrorAction = 'Stop'
        Force       = $true
        ItemType    = 'Directory'
        Path        = $DownloadPath
    }
    if (-not (Test-Path -LiteralPath $ItemParams.Path -ErrorAction SilentlyContinue)) {
        New-Item @ItemParams | Out-Null
    }
    #=================================================
    # Log selected cache file for traceability.
    # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] OSDCoreCacheContent: $($CacheDriverPack.FullName)"
    $DestinationFile = $null

    # Re-check destination (defensive) in case another step created it.
    # This avoids unnecessary copy work in race conditions.
    if (Test-Path -LiteralPath $LocalDestinationPath) {
        $DestinationFile = Get-Item -LiteralPath $LocalDestinationPath -ErrorAction SilentlyContinue
    }

    # If destination exists and byte length matches cache, skip recopy.
    if ($DestinationFile -and $DestinationFile.Length -eq $CacheDriverPack.Length) {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Cached file already exists at destination with matching size"
    }
    else {
        # Copy with -Force so partial/older files are replaced atomically by Copy-Item.
        # Any copy failure is terminal for this step because no valid destination exists.
        # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Copying $($CacheDriverPack.FullName)"
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Copying to $LocalDestinationPath"
        try {
            $null = Copy-Item -LiteralPath $CacheDriverPack.FullName -Destination $LocalDestinationPath -Force -ErrorAction Stop
        }
        catch {
            Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Failed to copy CacheDriverPack from $($CacheDriverPack.FullName) to $LocalDestinationPath. $($_.Exception.Message)"
            return
        }
    }
    #=================================================
    # Confirm destination exists and cache file info for downstream workflow.
    # Re-reading FileInfo ensures size/path metadata reflects the actual destination.
    if (Test-Path -LiteralPath $LocalDestinationPath) {
        $DestinationFile = Get-Item -LiteralPath $LocalDestinationPath -ErrorAction SilentlyContinue
        # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Destination file exists: $($DestinationFile.FullName)"
        # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Size: $($DestinationFile.Length) bytes"
    }
    else {
        Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Destination file does not exist after copy: $LocalDestinationPath"
        return
    }
    #=================================================
    # Final integrity check on the destination file.
    # Verify Cache file hash matches metadata after copy to ensure integrity.
    if ($DriverPackCloudObject.HashMD5) {
        $DestinationFileHash = Get-FileHash -Path $DestinationFile.FullName -Algorithm MD5
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Destination MD5: $($DestinationFileHash.Hash)"
        if ($DestinationFileHash.Hash -ne $DriverPackCloudObject.HashMD5) {
            Write-Host -ForegroundColor DarkYellow "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] - MD5 hash mismatch for destination file, deleting: $LocalDestinationPath"
            Remove-Item -LiteralPath $LocalDestinationPath -Force -ErrorAction SilentlyContinue
            return
        }
    }
    $global:RecastOSDCloud.DriverPackFileObject = $DestinationFile
    $global:RecastOSDCloud.DriverPackCloudObjectTest = $false
    #=================================================
    # Store this as a FileInfo Object
    $DriverPackCloudObject | ConvertTo-Json | Out-File "$($DestinationFile.FullName).json" -Encoding ascii -Width 2000 -Force
    #=================================================
    # Expand the DriverPack
    $DownloadedFile = $DestinationFile.FullName
    $ExpandPath = 'C:\Windows\Temp\osdcloud-driverpack-expand'
    if (-not (Test-Path "$ExpandPath")) {
        New-Item $ExpandPath -ItemType Directory -Force -ErrorAction Ignore | Out-Null
    }
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] DriverPack: $DownloadedFile"
    #=================================================
    # Cab
    #=================================================
    if ($DestinationFile.Extension -eq '.cab') {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Expand CAB DriverPack to $ExpandPath"
        Expand -R "$DownloadedFile" -F:* "$ExpandPath" | Out-Null

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Apply drivers in $ExpandPath"

        if ($env:SystemDrive -eq 'X:') {
            Add-WindowsDriver -Path "C:\" -Driver $ExpandPath -Recurse -ForceUnsigned -LogPath "$LogPath\dism-add-windowsdriver-driverpack.log" -ErrorAction SilentlyContinue | Out-Null
        }

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Windows\Temp\osdcloud-driverpack-download"
        Remove-Item -Path "C:\Windows\Temp\osdcloud-driverpack-download" -Recurse -Force -ErrorAction SilentlyContinue

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing $ExpandPath"
        Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Drivers"
        Remove-Item -Path "C:\Drivers" -Recurse -Force -ErrorAction SilentlyContinue
        return
    }
    #=================================================
    # Zip
    #=================================================
    if ($DestinationFile.Extension -eq '.zip') {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Expand ZIP DriverPack to $ExpandPath"
        Expand-Archive -Path $DownloadedFile -DestinationPath $ExpandPath -Force

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Apply drivers in $ExpandPath"
        if ($env:SystemDrive -eq 'X:') {
            Add-WindowsDriver -Path "C:\" -Driver $ExpandPath -Recurse -ForceUnsigned -LogPath "$LogPath\dism-add-windowsdriver-driverpack.log" -ErrorAction SilentlyContinue | Out-Null
        }

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Windows\Temp\osdcloud-driverpack-download"
        Remove-Item -Path "C:\Windows\Temp\osdcloud-driverpack-download" -Recurse -Force -ErrorAction SilentlyContinue

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing $ExpandPath"
        Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Drivers"
        Remove-Item -Path "C:\Drivers" -Recurse -Force -ErrorAction SilentlyContinue
        return
    }
    #=================================================
    # Dell
    #=================================================
    if (($DestinationFile.Extension -eq '.exe') -and ($DestinationFile.VersionInfo.FileDescription -match 'Dell')) {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] FileDescription: $($DestinationFile.VersionInfo.FileDescription)"
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] ProductVersion: $($DestinationFile.VersionInfo.ProductVersion)"

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Expand Dell DriverPack to $ExpandPath"
        $null = New-Item -Path $ExpandPath -ItemType Directory -Force -ErrorAction Ignore | Out-Null
        Start-Process -FilePath $DownloadedFile -ArgumentList "/s /e=`"$ExpandPath`"" -Wait

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Apply drivers in $ExpandPath"
        if ($env:SystemDrive -eq 'X:') {
            Add-WindowsDriver -Path "C:\" -Driver $ExpandPath -Recurse -ForceUnsigned -LogPath "$LogPath\dism-add-windowsdriver-driverpack.log" -ErrorAction SilentlyContinue | Out-Null
        }

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Windows\Temp\osdcloud-driverpack-download"
        Remove-Item -Path "C:\Windows\Temp\osdcloud-driverpack-download" -Recurse -Force -ErrorAction SilentlyContinue

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing $ExpandPath"
        Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Drivers"
        Remove-Item -Path "C:\Drivers" -Recurse -Force -ErrorAction SilentlyContinue
        return
    }
    #=================================================
    # HP
    #=================================================
    if (($DestinationFile.Extension -eq '.exe') -and ($DestinationFile.VersionInfo.InternalName -match 'hpsoftpaqwrapper')) {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] FileDescription: $($DestinationFile.VersionInfo.FileDescription)"
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] InternalName: $($DestinationFile.VersionInfo.InternalName)"
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] ProductVersion: $($DestinationFile.VersionInfo.ProductVersion)"

        if (Test-Path -Path $env:windir\System32\7za.exe) {
            Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Expand HP DriverPack to $ExpandPath"
            # Start-Process -FilePath $DownloadedFile -ArgumentList "/s /e /f `"$ExpandPath`"" -Wait
            & 7za x "$DownloadedFile" -o"C:\Windows\Temp\osdcloud-driverpack-expand"

            Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Apply drivers in $ExpandPath"
            if ($env:SystemDrive -eq 'X:') {
                Add-WindowsDriver -Path "C:\" -Driver $ExpandPath -Recurse -ForceUnsigned -LogPath "$LogPath\dism-add-windowsdriver-driverpack.log" -ErrorAction SilentlyContinue | Out-Null
            }

            Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Windows\Temp\osdcloud-driverpack-download"
            Remove-Item -Path "C:\Windows\Temp\osdcloud-driverpack-download" -Recurse -Force -ErrorAction SilentlyContinue

            Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing $ExpandPath"
            Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue

            Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Removing C:\Drivers"
            Remove-Item -Path "C:\Drivers" -Recurse -Force -ErrorAction SilentlyContinue
        }
        else {
            Write-Warning "[$(Get-Date -format s)] 7zip 7za.exe needs to be added to WinPE to expand HP DriverPacks"
            Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] HP DriverPack is saved at $DownloadedFile"

            Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue
            Remove-Item -Path "C:\Drivers" -Recurse -Force -ErrorAction SilentlyContinue
        }
        return
    }
    #=================================================
    # Lenovo
    #=================================================
    if (($DestinationFile.Extension -eq '.exe') -and ($DriverPackCloudObject.Manufacturer -match 'Lenovo')) {
        if (-not (Test-Path $ScriptsPath)) {
            New-Item -Path $ScriptsPath -ItemType Directory -Force -ErrorAction Ignore | Out-Null
        }
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Adding Lenovo DriverPack to $SetupCompleteCmd"

$Content = @"
:: ========================================================
:: OSDCloud DriverPack Installation for Lenovo
:: ========================================================
$DownloadedFile /SILENT /SUPPRESSMSGBOXES
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UnattendSettings\PnPUnattend\DriverPaths\1" /v Path /t REG_SZ /d "C:\Drivers" /f
pnpunattend.exe AuditSystem /L
reg delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UnattendSettings\PnPUnattend\DriverPaths\1" /v Path /f
rd /s /q C:\Drivers
rd /s /q C:\Windows\Temp\osdcloud-driverpack-download
:: ========================================================
"@

        $Content | Out-File -FilePath $SetupCompleteCmd -Append -Encoding ascii -Width 2000 -Force
        Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue
        return
    }
    #=================================================
    # Surface
    #=================================================
    if (($DestinationFile.Extension -eq '.msi') -and ($DestinationFile.Name -match 'surface')) {
        if (-not (Test-Path $ScriptsPath)) {
            New-Item -Path $ScriptsPath -ItemType Directory -Force -ErrorAction Ignore | Out-Null
        }
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Adding Surface DriverPack to $SetupCompleteCmd"

$Content = @"
:: ========================================================
:: OSDCloud DriverPack Installation for Microsoft Surface
:: ========================================================
msiexec /i $DownloadedFile /qn /norestart /l*v C:\Windows\Temp\osdcloud-logs\drivers-driverpack-microsoft.log
rd /s /q C:\Windows\Temp\osdcloud-driverpack-download
:: ========================================================
"@

        $Content | Out-File -FilePath $SetupCompleteCmd -Append -Encoding ascii -Width 2000 -Force
        Remove-Item -Path $ExpandPath -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path "C:\Drivers" -Recurse -Force -ErrorAction SilentlyContinue
        return
    }
    #=================================================
    Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] End"
    #=================================================
}