private/Expand-WinPEDriverPackageIso.ps1

#Requires -PSEdition Core

function Expand-WinPEDriverPackageIso {
    <#
    .SYNOPSIS
        Expands an ISO image to a destination directory
 
    .DESCRIPTION
        Validates that the source ISO exists, creates the destination directory when
        needed, mounts the image, and copies its contents to the destination. The function
        dismounts an image that it successfully mounted even when copying fails. A mount,
        volume discovery, or copy failure causes a terminating error.
 
    .PARAMETER Path
        Specifies the path to the ISO image. The path must resolve before the destination
        directory is created.
 
    .PARAMETER DestinationPath
        Specifies the directory that receives the ISO contents. The function creates the
        directory when it does not exist.
 
    .EXAMPLE
        PS> Expand-WinPEDriverPackageIso -Path 'C:\Drivers\WinPE.iso' -DestinationPath 'C:\Drivers\WinPE'
 
        Mounts WinPE.iso, copies its contents to C:\Drivers\WinPE, dismounts the image,
        and returns the destination directory.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.IO.DirectoryInfo. Returns the destination directory after the ISO contents
        are copied successfully.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-08-28
 
        Dependencies:
          PowerShell Modules: Storage
          DotNet Classes: System.IO.DirectoryInfo, System.IO.FileNotFoundException,
                          System.InvalidOperationException,
                          System.Management.Automation.ErrorCategory,
                          System.Management.Automation.ErrorRecord
    #>

    [CmdletBinding()]
    [OutputType([System.IO.DirectoryInfo])]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$DestinationPath
    )

    if (-not (Test-Path -Path $Path)) {
        $PSCmdlet.ThrowTerminatingError(
            [System.Management.Automation.ErrorRecord]::new(
                [System.IO.FileNotFoundException]::new("ISO file not found: $Path"),
                'IsoFileNotFound',
                [System.Management.Automation.ErrorCategory]::ObjectNotFound,
                $Path
            )
        )
    }

    if (-not (Test-Path -Path $DestinationPath)) {
        New-Item -ItemType Directory -Path $DestinationPath -Force | Out-Null
    }

    # Track whether mounting succeeded so cleanup does not attempt to dismount an unrelated image.
    $diskImage = $null
    try {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Mounting ISO: $Path"
        $diskImage = Mount-DiskImage -ImagePath $Path -PassThru -ErrorAction Stop
        $driveLetter = ($diskImage | Get-Volume).DriveLetter
        # A mounted image without a volume cannot provide a filesystem source to copy.
        if (-not $driveLetter) {
            throw "Could not determine drive letter for mounted ISO '$Path'."
        }

        $sourceRoot = "${driveLetter}:\"
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Copying ISO contents from '$sourceRoot' to '$DestinationPath'"
        Copy-Item -Path "${sourceRoot}*" -Destination $DestinationPath -Recurse -Force

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] ISO extraction complete: $DestinationPath"
        Get-Item -Path $DestinationPath
    }
    catch {
        $PSCmdlet.ThrowTerminatingError(
            [System.Management.Automation.ErrorRecord]::new(
                [System.InvalidOperationException]::new(
                    "ISO expansion failed for '$Path': $($_.Exception.Message)"
                ),
                'IsoExpandFailed',
                [System.Management.Automation.ErrorCategory]::InvalidResult,
                $Path
            )
        )
    }
    finally {
        # Always release a successfully mounted image, including after copy failures.
        if ($diskImage) {
            Dismount-DiskImage -ImagePath $Path -ErrorAction SilentlyContinue | Out-Null
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Dismounted ISO: $Path"
        }
    }
}