private/Import-OSDeployCoreWinPEDriversFromDrive.ps1

function Import-OSDeployCoreWinPEDriversFromDrive {
    <#
    .SYNOPSIS
        Imports WinPE driver folders from other drives into the OSDeploy Core Boot-Assets library
 
    .DESCRIPTION
        Scans file system drives other than the system drive for
        OSDeployCore\boot-assets\winpedrivers-amd64 and winpedrivers-arm64. Each top-level
        driver folder that does not already exist in the matching Boot-Assets
        winpedrivers-amd64 or winpedrivers-arm64 directory is copied recursively. Existing
        destination folders are never overwritten. When the same folder exists on more than
        one drive, the first drive found is used.
 
    .PARAMETER DriveRoot
        Specifies the drive roots to scan, such as 'E:\'. When omitted, all single-letter
        FileSystem PSDrives except the system drive are scanned.
 
    .PARAMETER BootAssetsPath
        Specifies the destination Boot-Assets path. Defaults to $script:OSDeployBootAssetsPath.
 
    .EXAMPLE
        PS> Import-OSDeployCoreWinPEDriversFromDrive
 
        Copies missing driver folders from all non-system drives into Boot-Assets.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.IO.DirectoryInfo. Returns each imported destination directory.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-10-02
    #>

    [CmdletBinding(SupportsShouldProcess)]
    [OutputType([System.IO.DirectoryInfo])]
    param (
        [Parameter()]
        [System.String[]]
        $DriveRoot,

        [Parameter()]
        [System.String]
        $BootAssetsPath = $script:OSDeployBootAssetsPath
    )

    if (-not $BootAssetsPath) {
        Write-Warning "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Boot-Assets path is not initialized."
        return
    }

    if (-not $DriveRoot) {
        $systemDriveLetter = ($env:SystemDrive -replace ':.*$', '')
        $DriveRoot = Get-PSDrive -PSProvider 'FileSystem' -ErrorAction SilentlyContinue |
            Where-Object { $_.Name.Length -eq 1 -and $_.Name -ne $systemDriveLetter -and $_.Root -match '^[A-Z]:\\$' } |
            ForEach-Object { $_.Root }
    }

    $destinationRootFull = [System.IO.Path]::GetFullPath($BootAssetsPath).TrimEnd('\')

    foreach ($root in $DriveRoot) {
        foreach ($arch in 'amd64', 'arm64') {
            $folderName = "winpedrivers-$arch"
            $sourcePath = Join-Path $root "OSDeployCore\boot-assets\$folderName"
            if (-not (Test-Path -LiteralPath $sourcePath -PathType Container)) {
                continue
            }

            $destinationPath = Join-Path $BootAssetsPath $folderName
            if ([System.IO.Path]::GetFullPath($sourcePath).TrimEnd('\') -ieq (Join-Path $destinationRootFull $folderName)) {
                continue
            }

            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Checking $sourcePath"
            foreach ($sourceFolder in (Get-ChildItem -LiteralPath $sourcePath -Directory -ErrorAction SilentlyContinue)) {
                $targetPath = Join-Path $destinationPath $sourceFolder.Name
                if (Test-Path -LiteralPath $targetPath) {
                    continue
                }

                if ($PSCmdlet.ShouldProcess($targetPath, "Import WinPE driver folder from $($sourceFolder.FullName)")) {
                    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Importing WinPE driver folder: $($sourceFolder.FullName)"
                    try {
                        if (-not (Test-Path -LiteralPath $destinationPath)) {
                            New-Item -Path $destinationPath -ItemType Directory -Force -ErrorAction Stop | Out-Null
                        }
                        Copy-Item -LiteralPath $sourceFolder.FullName -Destination $targetPath -Recurse -Force -ErrorAction Stop
                        Get-Item -LiteralPath $targetPath
                    }
                    catch {
                        # Remove partial copies so the folder is retried on the next run.
                        Remove-Item -LiteralPath $targetPath -Recurse -Force -ErrorAction SilentlyContinue
                        Write-Warning "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Failed to import $($sourceFolder.FullName): $($_.Exception.Message)"
                    }
                }
            }
        }
    }
}