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
        OSDCloud\winpedrivers-amd64, OSDCloud\winpedrivers-arm64, and the matching
        OSDeployCore\boot-assets folders. Each top-level driver folder that does not already
        exist in the matching Boot-Assets architecture directory is copied recursively.
        Existing destination folders are never overwritten. When a folder exists in both
        source locations on the same drive, the OSDCloud copy is preferred. 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"
            $destinationPath = Join-Path $BootAssetsPath $folderName
            $destinationArchitecturePath = Join-Path $destinationRootFull $folderName
            $sourcePaths = @(
                (Join-Path $root "OSDCloud\$folderName")
                (Join-Path $root "OSDeployCore\boot-assets\$folderName")
            )

            foreach ($sourcePath in $sourcePaths) {
                if (-not (Test-Path -LiteralPath $sourcePath -PathType Container)) {
                    continue
                }

                if ([System.IO.Path]::GetFullPath($sourcePath).TrimEnd('\') -ieq $destinationArchitecturePath) {
                    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)"
                        }
                    }
                }
            }
        }
    }
}