private/Initialize-OSDeployCoreBootAssets.ps1

function Initialize-OSDeployCoreBootAssets {
    <#
    .SYNOPSIS
        Initializes the OSDeployCore Boot-Assets directory
 
    .DESCRIPTION
        Moves legacy OSDeployCore content into the current Boot-Assets directory. Legacy
        paths are processed in the order supplied, so existing destination content and
        content from earlier paths take precedence.
 
        When both source and destination content exist, nonconflicting items are moved
        recursively. Conflicting source items remain unchanged and produce warnings. Empty
        legacy directories are removed after their content is migrated. The destination is
        created when Create is specified and no legacy directory can be moved.
 
    .PARAMETER LegacyPath
        Specifies one or more legacy content directories in descending precedence order.
        Missing directories are ignored.
 
    .PARAMETER BootAssetsPath
        Specifies the destination path for the current Boot-Assets directory.
 
    .PARAMETER Create
        Creates the Boot-Assets directory when it does not exist after migration.
 
    .EXAMPLE
        PS> Initialize-OSDeployCoreBootAssets -LegacyPath 'C:\ProgramData\OSDeployCore\repository', 'C:\ProgramData\OSDeployCore\OSDRepo' -BootAssetsPath 'C:\ProgramData\OSDeployCore\boot-assets' -Create
 
        Migrates nonconflicting legacy content into Boot-Assets and creates the destination
        when no legacy directory exists.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        None.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-09-11
 
        The source and destination parents must permit directory moves. Migration failures
        are reported as warnings and do not produce terminating errors.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [System.String[]]
        $LegacyPath,

        [Parameter(Mandatory)]
        [System.String]
        $BootAssetsPath,

        [System.Management.Automation.SwitchParameter]
        $Create
    )

    $functionName = $MyInvocation.MyCommand.Name
    $moveDirectoryContent = {
        param (
            [System.String]$SourcePath,
            [System.String]$DestinationPath
        )

        if (-not (Test-Path -LiteralPath $DestinationPath -PathType Container)) {
            try {
                Move-Item -LiteralPath $SourcePath -Destination $DestinationPath -ErrorAction Stop
                Write-Verbose "[$functionName] Migrated Boot-Assets content from '$SourcePath' to '$DestinationPath'"
            }
            catch {
                Write-Warning "[$functionName] Could not migrate '$SourcePath' to '$DestinationPath': $($_.Exception.Message)"
            }
            return
        }

        foreach ($item in @(Get-ChildItem -LiteralPath $SourcePath -Force -ErrorAction SilentlyContinue)) {
            $destinationItem = Join-Path $DestinationPath $item.Name
            if (-not (Test-Path -LiteralPath $destinationItem)) {
                try {
                    Move-Item -LiteralPath $item.FullName -Destination $destinationItem -ErrorAction Stop
                    Write-Verbose "[$functionName] Migrated Boot-Assets content from '$($item.FullName)' to '$destinationItem'"
                }
                catch {
                    Write-Warning "[$functionName] Could not migrate '$($item.FullName)' to '$destinationItem': $($_.Exception.Message)"
                }
                continue
            }

            if ($item.PSIsContainer -and (Test-Path -LiteralPath $destinationItem -PathType Container)) {
                & $moveDirectoryContent $item.FullName $destinationItem
                continue
            }

            Write-Warning "[$functionName] Boot-Assets content already exists at '$destinationItem'. Legacy content remains at '$($item.FullName)'."
        }

        if (-not (Get-ChildItem -LiteralPath $SourcePath -Force -ErrorAction SilentlyContinue | Select-Object -First 1)) {
            Remove-Item -LiteralPath $SourcePath -Force -ErrorAction SilentlyContinue
        }
    }

    foreach ($path in $LegacyPath) {
        if ([System.String]::IsNullOrWhiteSpace($path) -or
            $path.Equals($BootAssetsPath, [System.StringComparison]::OrdinalIgnoreCase) -or
            -not (Test-Path -LiteralPath $path -PathType Container)) {
            continue
        }

        & $moveDirectoryContent $path $BootAssetsPath
    }

    if ($Create -and -not (Test-Path -LiteralPath $BootAssetsPath -PathType Container)) {
        try {
            New-Item -ItemType Directory -Path $BootAssetsPath -Force -ErrorAction Stop | Out-Null
            Write-Verbose "[$functionName] Created Boot-Assets directory: $BootAssetsPath"
        }
        catch {
            Write-Warning "[$functionName] Could not create Boot-Assets directory '$BootAssetsPath': $($_.Exception.Message)"
        }
    }
}