Public/Invoke-WinBuilderTask.ps1

function Invoke-WinBuilderTask {
    [CmdletBinding(DefaultParameterSetName = "TaskName")]
    Param (
        [Parameter(ParameterSetName = "TaskName", Mandatory = $true, Position = 0)]
        [string]$TaskName,
        [Parameter(ParameterSetName = "TaskPath", Mandatory = $true, Position = 0)]
        [string]$TaskPath
    )

    $ProjectRoot = $global:WinBuilderProject
    $DriverRoot = $ProjectRoot + '\drivers'
    $RegisteryRoot = $ProjectRoot + '\registries'
    $PackageRoot = $ProjectRoot + '\packages'

    $chosen = $PSCmdlet.ParameterSetName
    if ($chosen -eq "TaskName") {
        $TaskPath = "$ProjectRoot\tasks\$TaskName.json"
    }
    $content = Get-Content $TaskPath | ConvertFrom-Json

    $TempDirectory = "$ProjectRoot\build\$(Get-Random)"
    if (!(Test-Path $TempDirectory)) { New-Item -Path "$TempDirectory" -ItemType Directory -Force | Out-Null }

    #======================================================================================
    # Import-Image
    #======================================================================================
    $ISOPath = "$ProjectRoot\iso\$($content.ISO)"
    $DevicePath = (Mount-ISO -Path $ISOPath).DevicePath
    $Letter = (Get-DiskImage -DevicePath $DevicePath | Get-Volume).DriveLetter
    $IsoLabel = (Get-DiskImage -DevicePath $DevicePath | Get-Volume).FileSystemLabel

    # Create media directory
    $MediaPath = "$TempDirectory\media"
    if (!(Test-Path $MediaPath)) { New-Item -Path "$MediaPath" -ItemType Directory -Force | Out-Null }
    Copy-Item -Path "${Letter}:\*" -Destination "${MediaPath}" -Exclude @("boot.wim", "install.wim") -Recurse

    # boot.wim
    $ImagesInfo = Get-ImageFiles -DriveLetter $Letter -Include ("boot.wim") | Sort-Object -Property ImageIndex
    $ImagePath = "$TempDirectory\boot.wim"
    if (Test-Path $ImagePath) { Remove-Item -Force $ImagePath }
    $ImagesInfo | ForEach-Object {
        Export-Image $_.ImagePath $_.ImageIndex $ImagePath
    }

    # install.wim
    $ImagesInfo = Get-ImageFiles -DriveLetter $Letter -Include install.wim, install.esd
    $ImagePath = "$TempDirectory\install.wim"
    if (Test-Path $ImagePath) { Remove-Item -Force $ImagePath }
    $ImagesInfo |  Where-Object { $content.Editions -match $_.EditionId } | ForEach-Object {
        Export-Image $_.ImagePath $_.ImageIndex $ImagePath
    }

    $null = Dismount-ISO -Path $ISOPath

    # Create mount directory
    $MountPath = "$TempDirectory\mount"
    if (!(Test-Path $MountPath)) { New-Item -Path "$MountPath" -ItemType Directory -Force | Out-Null }

    #======================================================================================
    # Edit-BootImage
    #======================================================================================
    $ImagePath = "$TempDirectory\boot.wim"
    Get-WindowsImage -ImagePath $ImagePath | ForEach-Object {
        Mount-WindowsImage -Path $MountPath -ImagePath $_.ImagePath -Index $_.ImageIndex | Out-Null

        $content.BootDrivers | ForEach-Object {
            if ($_.EndsWith(".json")) {
                Add-WimDriver -Path $MountPath -JsonPath "$DriverRoot\$_"
            }
            else {
                Add-WimDriver -Path $MountPath -DriverPath "$DriverRoot\$_"
            }
        }

        Dismount-WindowsImage -Path $MountPath -Save | Out-Null
    }
    $TempImagePath = "$TempDirectory\$(Get-Random).wim"
    Export-Image -SourceImagePath $ImagePath -DestinationImagePath $TempImagePath
    Move-Item -Force $TempImagePath $ImagePath

    #======================================================================================
    # Edit-MainImage
    #======================================================================================
    $ImagePath = "$TempDirectory\install.wim"
    $ImagesInfo = Get-WindowsImage -ImagePath $ImagePath | Sort-Object -Property ImageIndex | ForEach-Object {
        Get-WindowsImage -ImagePath $_.ImagePath -Index $_.ImageIndex
    }
    $ImagesInfo | ForEach-Object {
        #======================================================================================
        # Mount-MainImage
        #======================================================================================
        Mount-WindowsImage -Path $MountPath -ImagePath $_.ImagePath -Index $_.ImageIndex | Out-Null

        #======================================================================================
        # Add-Drivers
        #======================================================================================
        $content.Drivers | ForEach-Object {
            if ($_.EndsWith(".json")) {
                Add-WimDriver -Path $MountPath -JsonPath "$DriverRoot\$_"
            }
            else {
                Add-WimDriver -Path $MountPath -DriverPath "$DriverRoot\$_"
            }
        }

        #======================================================================================
        # Add-Registries
        #======================================================================================
        $RegFiles = $content.Registries | ForEach-Object { Get-Item "$RegisteryRoot\$_" }
        Import-OfflineRegistry -Path $MountPath -RegFiles $RegFiles

        #======================================================================================
        # Deploy-AppxPackages
        #======================================================================================
        $content.AppxPackages | ForEach-Object {
            if ($_.action -eq "remove") {
                Remove-WimAppxPackage -Path $MountPath -PackageName $_.name
            }
        }

        #======================================================================================
        # Add-Packages
        #======================================================================================
        $content.Packages | ForEach-Object {
            Dism /Image=$MountPath /Add-ProvisioningPackage /PackagePath:"$PackageRoot\$_"
        }

        #======================================================================================
        # Save-Image
        #======================================================================================
        Write-Host "Will dismount!"
        # cmd /c pause
        Dismount-WindowsImage -Path $MountPath -Save | Out-Null
    }

    #======================================================================================
    # Clean-Image
    #======================================================================================
    $TempImagePath = "$TempDirectory\$(Get-Random).wim"
    Export-Image -SourceImagePath $ImagePath -DestinationImagePath $TempImagePath
    Move-Item -Force $TempImagePath $ImagePath

    Move-Item -Path "$TempDirectory\boot.wim" -Destination "$MediaPath\sources\"
    Move-Item -Path "$TempDirectory\install.wim" -Destination "$MediaPath\sources\"

    #======================================================================================
    # Add-Unattend
    #======================================================================================
    if ($content.PSobject.Properties.name -match "Unattend") {
        # $DestDir = "$MountPath\Windows\Panther\Unattend"
        # if (!(Test-Path $DestDir)) { New-Item -Path $DestDir -ItemType Directory -Force | Out-Null }
        # Copy-Item -Path "$ProjectRoot\configs\$($content.Unattend)" -Destination $DestDir\Unattend.xml
        Copy-Item -Path "$ProjectRoot\configs\$($content.Unattend)" -Destination $MediaPath\AutoUnattend.xml
    }

    #======================================================================================
    # Add-OEM-Files
    #======================================================================================
    if ($content.PSobject.Properties.name -match "OEM") {
        $OemRoot = $ProjectRoot + '\oem'
        $OemDirectory = "$MediaPath\sources\`$OEM`$"
        if (!(Test-Path $OemDirectory)) { New-Item -Path $OemDirectory -ItemType Directory -Force | Out-Null }
        $content.OEM | ForEach-Object {
            Copy-Item -Path "$OemRoot\$($_.action)\*" -Destination "$OemDirectory\" -Recurse -Force
            $appPath = $_.path
            if ($_.action -eq "audit_install") {
                $_.packages | ForEach-Object {
                    Copy-Item -Path "$PackageRoot\$_.exe" -Destination "$OemDirectory\`$`$\OEM\$appPath"
                }
            }
            if ($_.action -eq "oobe_install") {
                $_.packages | ForEach-Object {
                    Copy-Item -Path "$PackageRoot\$_.exe" -Destination "$OemDirectory\`$`$\OEM\$appPath"
                }
            }
        }
    }

    $orderFile = Get-Content "$((Get-Item $PSScriptRoot).Parent.FullName)\Private\bootOrder.txt"
    $orderFile | Out-File "$TempDirectory\bootOrder.txt" -Encoding ascii

    Set-DandIEnv
    $bootdata = '2#p0,e,b"{0}"#pEF,e,b"{1}"' -f `
        "$MediaPath\boot\etfsboot.com", `
        "$MediaPath\efi\microsoft\boot\efisys.bin"

        # -yo"$TempDirectory\bootOrder.txt" `
    oscdimg -bootdata:"$bootdata" `
        -u2 -udfver102 -l"$IsoLabel" -m -o `
        "$MediaPath" "$TempDirectory\win.iso"
    
    if ($content.PSobject.Properties.name -match "Output") {
        Move-Item -Path "$TempDirectory\win.iso" -Destination $content.Output -Force
    }
}