Update-OSMedia.ps1

function Update-OSMedia {
    [CmdletBinding()]
    Param (
        [string]$ByName,
        [switch]$DownloadUpdates,
        [switch]$Execute
    )
    #======================================================================================
    # Start 18.9.13
    #======================================================================================
    Write-Host "===========================================================================" -ForegroundColor Green
    Write-Host "Update-OSMedia" -ForegroundColor Green
    Write-Host "===========================================================================" -ForegroundColor Green
    #======================================================================================
    # Validate Administrator Rights 18.9.13
    #======================================================================================
    if (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
            [Security.Principal.WindowsBuiltInRole] "Administrator"))
    {
        Write-Host ""
        Write-Host "This function needs to be run as Administrator" -ForegroundColor Yellow
        Write-Host ""
        Return
    }
    #======================================================================================
    # Initialize OSBuilder 18.9.13
    #======================================================================================
    Get-OSBuilder -CreatePaths -HideDetails
    #======================================================================================
    # Validate OSMedia has content 18.9.13
    #======================================================================================
    $AllOSMedia = Get-ChildItem -Path "$OSMediaPath" -Directory | Where-Object {$_.Name -like "*.*"} | Select-Object -Property Name, FullName, CreationTime
    if ($null -eq $AllOSMedia) {
        Write-Warning "OSMedia content not found. Use Import-OSMedia to import an Operating System first . . . Exiting!"
        Break
    }
    #======================================================================================
    # Validate OSMedia has an install.wim 18.9.13
    #======================================================================================
    $AllOSMedia = $AllOSMedia | Where-Object {Test-Path $(Join-Path $_.FullName (Join-Path "OS" (Join-Path "sources" "install.wim")))}
    if ($null -eq $AllOSMedia) {
        Write-Warning "OSMedia Install.wim not found. Use Import-OSMedia to import an Operating System first . . . Exiting!"
        Break
    }
    #======================================================================================
    # Validate OSMedia was imported with Import-OSMedia 18.9.13
    #======================================================================================
    $AllOSMedia = $AllOSMedia | Where-Object {Test-Path $(Join-Path $_.FullName "WindowsImage.txt")}
    if ($null -eq $AllOSMedia) {
        Write-Warning "OSMedia content invalid (missing WindowsImage.txt). Use Import-OSMedia to import an Operating System first . . . Exiting!"
        Break
    }
    #======================================================================================
    # Select Source OSMedia 18.9.13
    #======================================================================================
    if ($ByName) {
        $AllOSMedia = $AllOSMedia | Where-Object {$_.Name -like "*$ByName*" -or $_.FullName -like "*$ByName*"}
        if ($null -eq $AllOSMedia) {
            Write-Warning "Could not find a matching OSMedia to update . . . Exiting!"
            Break
        }
    } else {
        $AllOSMedia = $AllOSMedia | Out-GridView -Title "Select a Source OSMedia to Update (Cancel to Exit)" -PassThru
        if($null -eq $AllOSMedia) {
            Write-Warning "Source OSMedia was not selected . . . Exiting!"
            Break
        }
    }
    if ($AllOSMedia.Count -gt 1) {
        Write-Warning "Updating Multiple Operating Systems. This may take some time ..."
    }
    #======================================================================================
    # Evaluate OSMediaFullPath 18.9.13
    #======================================================================================
 <# if ($OSMediaFullPath) {
        if (!(Test-Path $(Join-Path $OSMediaFullPath (Join-Path "info" (Join-Path "json" "Get-WindowsImage.json"))))) {
            Write-Warning "Could not find an Operating System at this location to evaluate"
            Write-Warning "$OSMediaFullPath"
            Break
        } else {
            $AllOSMedia = Get-Item $OSMediaFullPath
        }
    } else {
        #======================================================================================
        # Select Source OSMedia 18.9.13
        #======================================================================================
    } #>

    #======================================================================================
    # Update OSMedia 18.9.13
    #======================================================================================
    foreach ($SelectedOSMedia in $AllOSMedia) {
        #======================================================================================
        # Get Windows Image Information
        #======================================================================================
        $OSSourcePath = "$($SelectedOSMedia.FullName)"
        $OSImagePath = "$OSSourcePath\OS\sources\install.wim"
        $OSImageIndex = 1
        $WindowsImage = Get-WindowsImage -ImagePath "$OSImagePath" -Index $OSImageIndex | Select-Object -Property *

        $OSImageName = $($WindowsImage.ImageName)
        $OSImageDescription = $($WindowsImage.ImageDescription)
        if ($($WindowsImage.Architecture) -eq 0) {$OSArchitecture = 'x86'}
        elseif ($($WindowsImage.Architecture) -eq 1) {$OSArchitecture = 'MIPS'}
        elseif ($($WindowsImage.Architecture) -eq 2) {$OSArchitecture = 'Alpha'}
        elseif ($($WindowsImage.Architecture) -eq 3) {$OSArchitecture = 'PowerPC'}
        elseif ($($WindowsImage.Architecture) -eq 6) {$OSArchitecture = 'ia64'}
        elseif ($($WindowsImage.Architecture) -eq 9) {$OSArchitecture = 'x64'}
        else {$OSArchitecture = $null}
        $OSEditionID = $($WindowsImage.EditionId)
        $OSInstallationType = $($WindowsImage.InstallationType)
        $OSLanguages = $($WindowsImage.Languages)
        $OSBuild = $($WindowsImage.Build)
        $OSVersion = $($WindowsImage.Version)
        $OSSPBuild = $($WindowsImage.SPBuild)
        $OSSPLevel = $($WindowsImage.SPLevel)
        $OSImageBootable = $($WindowsImage.ImageBootable)
        $OSWIMBoot = $($WindowsImage.WIMBoot)
        $OSCreatedTime = $($WindowsImage.CreatedTime)
        $OSModifiedTime = $($WindowsImage.ModifiedTime)
        #======================================================================================
        Write-Host "OSMedia Information" -ForegroundColor Yellow
        Write-Host "-Source Path: $OSSourcePath" -ForegroundColor Cyan
        Write-Host "-Image File: $OSImagePath" -ForegroundColor Cyan
        Write-Host "-Image Index: $OSImageIndex" -ForegroundColor Cyan
        Write-Host "-Name: $OSImageName" -ForegroundColor Cyan
        Write-Host "-Description: $OSImageDescription" -ForegroundColor Cyan
        Write-Host "-Architecture: $OSArchitecture" -ForegroundColor Cyan
        Write-Host "-Edition: $OSEditionID" -ForegroundColor Cyan
        Write-Host "-Type: $OSInstallationType" -ForegroundColor Cyan
        Write-Host "-Languages: $OSLanguages" -ForegroundColor Cyan
        Write-Host "-Build: $OSBuild" -ForegroundColor Cyan
        Write-Host "-Version: $OSVersion" -ForegroundColor Cyan
        Write-Host "-SPBuild: $OSSPBuild" -ForegroundColor Cyan
        Write-Host "-SPLevel: $OSSPLevel" -ForegroundColor Cyan
        Write-Host "-Bootable: $OSImageBootable" -ForegroundColor Cyan
        Write-Host "-WimBoot: $OSWIMBoot" -ForegroundColor Cyan
        Write-Host "-Created Time: $OSCreatedTime" -ForegroundColor Cyan
        Write-Host "-Modified Time: $OSModifiedTime" -ForegroundColor Cyan
        #======================================================================================
        if (Test-Path "$OSSourcePath\info\xml\CurrentVersion.xml") {
            $RegCurrentVersion = Import-Clixml -Path "$OSSourcePath\info\xml\CurrentVersion.xml"
            $OSVersionNumber = $($RegCurrentVersion.ReleaseId)
        } else {
            if ($OSBuild -eq 17134) {$OSVersionNumber = 1803}
            if ($OSBuild -eq 16299) {$OSVersionNumber = 1709}
            if ($OSBuild -eq 15063) {$OSVersionNumber = 1703}
            if ($OSBuild -eq 14393) {$OSVersionNumber = 1607}
            if ($OSBuild -eq 10240) {$OSVersionNumber = 1507}
        }
        #======================================================================================
        # Set Working Path
        #======================================================================================
        $BuildName = "build$((Get-Date).ToString('mmss'))"
        $WorkingPath = "$Script:OSMediaPath\$BuildName"
        #======================================================================================
        # Validate Exiting WorkingPath
        #======================================================================================
        if (Test-Path $WorkingPath) {
            Write-Warning "$WorkingPath exists. Contents will be replaced"
            Remove-Item -Path "$WorkingPath" -Force -Recurse
            Write-Host ""
        }
        #======================================================================================
        # Download Update Catalog 18.9.13
        #======================================================================================
        if (!(Test-Path $CatalogXml)) {Get-OSBuilderUpdates -CatalogUpdate -HideDetails}
        #======================================================================================
        # Get Current Updates XML 18.9.13
        #======================================================================================
        if (Test-Path $CatalogXml) {
            $Catalog = Import-Clixml -Path "$CatalogXml"
        } else {
            Write-Warning "Update Catalog does not exist. Exiting"
            Break
        }
        #======================================================================================
        # Update Adobe Path
        #======================================================================================
        $UpdateAdobe = $Catalog | Where-Object {$_.Category -eq 'Adobe'}
        $UpdateAdobe = $UpdateAdobe | Where-Object {$_.KBTitle -like "*$OSVersionNumber*"}
        $UpdateAdobe = $UpdateAdobe | Where-Object {$_.KBTitle -like "*$OSArchitecture*"}
        if ($OSInstallationType -like "*Server*") {
            $UpdateAdobe = $UpdateAdobe | Where-Object {$_.KBTitle -like "*Server*"}
        } else {
            $UpdateAdobe = $UpdateAdobe | Where-Object {$_.KBTitle -notlike "*Server*"}
        }
        #======================================================================================
        # Update Component Path
        #======================================================================================
        $UpdateComponent = $Catalog | Where-Object {$_.Category -eq 'Component'}
        $UpdateComponent = $UpdateComponent | Where-Object {$_.KBTitle -like "*$OSVersionNumber*"}
        $UpdateComponent = $UpdateComponent | Where-Object {$_.KBTitle -like "*$OSArchitecture*"}
        if ($OSInstallationType -like "*Server*") {
            $UpdateComponent = $UpdateComponent | Where-Object {$_.KBTitle -like "*Server*"}
        } else {
            $UpdateComponent = $UpdateComponent | Where-Object {$_.KBTitle -notlike "*Server*"}
        }
        $UpdateComponent = $UpdateComponent | Sort-Object -Property KBTitle
        #======================================================================================
        # Cumulative Updates
        #======================================================================================
        $UpdateCumulative = $Catalog | Where-Object {$_.Category -eq 'Cumulative'}
        $UpdateCumulative = $UpdateCumulative | Where-Object {$_.KBTitle -like "*$OSVersionNumber*"}
        $UpdateCumulative = $UpdateCumulative | Where-Object {$_.KBTitle -like "*$OSArchitecture*"}
        if ($OSInstallationType -like "*Server*") {
            $UpdateCumulative = $UpdateCumulative | Where-Object {$_.KBTitle -like "*Server*"}
        } else {
            $UpdateCumulative = $UpdateCumulative | Where-Object {$_.KBTitle -notlike "*Server*"}
        }
        $UpdateCumulative = $UpdateCumulative | Sort-Object -Property DatePosted
        #======================================================================================
        # Update Servicing Path
        #======================================================================================
        $UpdateServicing = $Catalog | Where-Object {$_.Category -eq 'Servicing'}
        $UpdateServicing = $UpdateServicing | Where-Object {$_.KBTitle -like "*$OSVersionNumber*"}
        $UpdateServicing = $UpdateServicing | Where-Object {$_.KBTitle -like "*$OSArchitecture*"}
        if ($OSInstallationType -like "*Server*") {
            $UpdateServicing = $UpdateServicing | Where-Object {$_.KBTitle -like "*Server*"}
        } else {
            $UpdateServicing = $UpdateServicing | Where-Object {$_.KBTitle -notlike "*Server*"}
        }
        #======================================================================================
        # Update Setup Path
        #======================================================================================
        $UpdateSetup = $Catalog | Where-Object {$_.Category -eq 'Setup'}
        $UpdateSetup = $UpdateSetup | Where-Object {$_.KBTitle -like "*$OSVersionNumber*"}
        $UpdateSetup = $UpdateSetup | Where-Object {$_.KBTitle -like "*$OSArchitecture*"}
        if ($OSInstallationType -like "*Server*") {
            $UpdateSetup = $UpdateSetup | Where-Object {$_.KBTitle -like "*Server*"}
        } else {
            $UpdateSetup = $UpdateSetup | Where-Object {$_.KBTitle -notlike "*Server*"}
        }
        #======================================================================================
        # Update Validation 18.9.13
        #======================================================================================
        Write-Host "===========================================================================" -ForegroundColor Yellow
        Write-Host "Updates to Apply" -ForegroundColor Yellow
        if ($DownloadUpdates.IsPresent) {Get-OSBuilderUpdates -CatalogUpdate -HideDetails}

        foreach ($Update in $UpdateAdobe) {
            $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
            if (!(Test-Path "$UpdatesPath\*\$($Update.KBTitle)\$($Update.FileName)")) {
                if ($DownloadUpdates.IsPresent) {
                    Write-Warning "Missing $($Update.KBTitle) ... Downloading"
                    Get-OSBuilderUpdates -KBTitle "$($Update.KBTitle)" -Download -HideDetails
                } else {
                    Write-Warning "Missing $($Update.KBTitle) ... Execution will be Disabled"
                    $Execute = $false
                }
            }
        }
        foreach ($Update in $UpdateComponent) {
            $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
            if (!(Test-Path "$UpdatesPath\*\$($Update.KBTitle)\$($Update.FileName)")) {
                if ($DownloadUpdates.IsPresent) {
                    Write-Warning "Missing $($Update.KBTitle) ... Downloading"
                    Get-OSBuilderUpdates -KBTitle "$($Update.KBTitle)" -Download -HideDetails
                } else {
                    Write-Warning "Missing $($Update.KBTitle) ... Execution will be Disabled"
                    $Execute = $false
                }
            }
        }
        foreach ($Update in $UpdateCumulative) {
            $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
            if (!(Test-Path "$UpdatesPath\*\$($Update.KBTitle)\$($Update.FileName)")) {
                if ($DownloadUpdates.IsPresent) {
                    Write-Warning "Missing $($Update.KBTitle) ... Downloading"
                    Get-OSBuilderUpdates -KBTitle "$($Update.KBTitle)" -Download -HideDetails
                } else {
                    Write-Warning "Missing $($Update.KBTitle) ... Execution will be Disabled"
                    $Execute = $false
                }
            }
        }
        foreach ($Update in $UpdateServicing) {
            $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
            if (!(Test-Path "$UpdatesPath\*\$($Update.KBTitle)\$($Update.FileName)")) {
                if ($DownloadUpdates.IsPresent) {
                    Write-Warning "Missing $($Update.KBTitle) ... Downloading"
                    Get-OSBuilderUpdates -KBTitle "$($Update.KBTitle)" -Download -HideDetails
                } else {
                    Write-Warning "Missing $($Update.KBTitle) ... Execution will be Disabled"
                    $Execute = $false
                }
            }
        }
        foreach ($Update in $UpdateSetup) {
            $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
            if (!(Test-Path "$UpdatesPath\*\$($Update.KBTitle)\$($Update.FileName)")) {
                if ($DownloadUpdates.IsPresent) {
                    Write-Warning "Missing $($Update.KBTitle) ... Downloading"
                    Get-OSBuilderUpdates -KBTitle "$($Update.KBTitle)" -Download -HideDetails
                } else {
                    Write-Warning "Missing $($Update.KBTitle) ... Execution will be Disabled"
                    $Execute = $false
                }
            }
        }
        #======================================================================================
        # Execute
        #======================================================================================
        if ($Execute.IsPresent) {
            $Info = Join-Path $WorkingPath 'info'
            $LogsJS = Join-Path $Info 'json'
            $LogsXML = Join-Path $Info 'xml'
            $Logs =    Join-Path $Info "logs"
            if (!(Test-Path "$Info"))        {New-Item "$Info" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$LogsJS"))        {New-Item "$LogsJS" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$LogsXML"))    {New-Item "$LogsXML" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$Logs"))        {New-Item "$Logs" -ItemType Directory -Force | Out-Null}

            $OS = Join-Path $WorkingPath "OS"
            $WinPE = Join-Path $WorkingPath "WinPE"
            if (!(Test-Path "$OS"))            {New-Item "$OS" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$WinPE"))        {New-Item "$WinPE" -ItemType Directory -Force | Out-Null}

            $PEInfo = Join-Path $WinPE 'info'
            $PELogsJS = Join-Path $PEInfo 'json'
            $PELogsXML = Join-Path $PEInfo 'xml'
            $PELogs =    Join-Path $PEInfo "logs"

            if (!(Test-Path "$PEInfo"))        {New-Item "$PEInfo" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$PELogsJS"))    {New-Item "$PELogsJS" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$PELogsXML"))    {New-Item "$PELogsXML" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path "$PELogs"))        {New-Item "$PELogs" -ItemType Directory -Force | Out-Null}

            $WimTemp = Join-Path $WorkingPath "WimTemp"
            if (!(Test-Path "$WimTemp"))    {New-Item "$WimTemp" -ItemType Directory -Force | Out-Null}
            #======================================================================================
            # Start the Transcript
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Starting Transcript" -ForegroundColor Yellow
            $ScriptName = $MyInvocation.MyCommand.Name
            $LogName = "$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-$ScriptName.log"
            Start-Transcript -Path (Join-Path $Logs $LogName)
            #======================================================================================
            # Display Build Paths 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Creating OSMedia $BuildName" -ForegroundColor Yellow
            Write-Host "Working Path: $WorkingPath" -ForegroundColor Yellow
            Write-Host "-Info: $Info" -ForegroundColor Cyan
            Write-Host "-Logs: $Logs" -ForegroundColor Cyan
            Write-Host "-OS: $OS" -ForegroundColor Cyan
            Write-Host "-WinPE: $WinPE" -ForegroundColor Cyan
            #======================================================================================
            # Create Mount Directories 18.9.10
            #======================================================================================
            $MountDirectory = Join-Path $MountPath "os$((Get-Date).ToString('mmss'))"
            if ( ! (Test-Path "$MountDirectory")) {New-Item "$MountDirectory" -ItemType Directory -Force | Out-Null}
            $MountWinPE = Join-Path $MountPath "winpe$((Get-Date).ToString('mmss'))"
            if ( ! (Test-Path "$MountWinPE")) {New-Item "$MountWinPE" -ItemType Directory -Force | Out-Null}
            $MountSetup = Join-Path $MountPath "setup$((Get-Date).ToString('mmss'))"
            if ( ! (Test-Path "$MountSetup")) {New-Item "$MountSetup" -ItemType Directory -Force | Out-Null}
            $MountWinRE = Join-Path $MountPath "winre$((Get-Date).ToString('mmss'))"
            if ( ! (Test-Path "$MountWinRE")) {New-Item "$MountWinRE" -ItemType Directory -Force | Out-Null}
            #======================================================================================
            # Copy OS 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Copying Operating System to $BuildName" -ForegroundColor Yellow
            Write-Host "Copying OS to $WorkingPath"
            Copy-Item -Path "$OSSourcePath\*" -Destination "$WorkingPath" -Exclude ('*.wim','*.iso') -Recurse -Force | Out-Null
            if (Test-Path "$WorkingPath\ISO"){Remove-Item -Path "$WorkingPath\ISO" -Force -Recurse | Out-Null}
            Write-Host "Copying install.wim to $WimTemp\install.wim"
            Copy-Item -Path "$OSSourcePath\OS\sources\install.wim" -Destination "$WimTemp\install.wim" -Force | Out-Null
            Write-Host "Copying WinPE to $WimTemp"
            Copy-Item -Path "$OSSourcePath\WinPE\*.wim" -Destination "$WimTemp" -Exclude boot.wim -Force | Out-Null
            #======================================================================================
            # Setup Update 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Setup Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateSetup)) {
                foreach ($Update in $UpdateSetup) {
                    $UpdateSetup = $(Get-ChildItem -Path $UpdatesPath -File -Recurse | Where-Object {$_.Name -eq $($Update.FileName)}).FullName
                    if (Test-Path "$UpdateSetup") {
                        Write-Host "expand.exe '$UpdateSetup' -F:*.* $OS\Sources"
                        expand.exe "$UpdateSetup" -F:*.* "$OS\Sources"
                    } else {
                        Write-Warning "Not Found: $UpdateSetup"
                    }
                }
            }
            #======================================================================================
            # WinPE Phase: Mount 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Mount Setup WIM" -ForegroundColor Yellow
            Mount-WindowsImage -ImagePath "$WimTemp\setup.wim" -Index 1 -Path "$MountSetup" -Optimize -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Mount-WindowsImage-setup.wim.log"
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Mount WinPE WIM" -ForegroundColor Yellow
            Mount-WindowsImage -ImagePath "$WimTemp\winpe.wim" -Index 1 -Path "$MountWinPE" -Optimize -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Mount-WindowsImage-winpe.wim.log"
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Mount WinRE WIM" -ForegroundColor Yellow
            Mount-WindowsImage -ImagePath "$WimTemp\winre.wim" -Index 1 -Path "$MountWinRE" -Optimize -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Mount-WindowsImage-winre.wim.log"
            #======================================================================================
            # WinPE Phase: Update Sources 18.9.10
            #======================================================================================
<# Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Updating Media Sources with Setup.wim" -ForegroundColor Yellow
            robocopy "$MountSetup" "$OS" setup.exe /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Setup-setup.wim.log"
            robocopy "$MountSetup\sources" "$OS\sources" *.* /e /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Sources-setup.wim.log" #>

            #======================================================================================
            # WinPE Phase: Servicing Update 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Servicing Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateServicing)) {
                foreach ($Update in $UpdateServicing) {
                    $UpdateSSU = $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
                    if (Test-Path "$UpdateSSU") {
                        Write-Host "setup.wim: $UpdateSSU"
                        if (Get-WindowsPackage -Path "$MountSetup" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {
                            Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                        } else {
                            Add-WindowsPackage -Path "$MountSetup" -PackagePath "$UpdateSSU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateServicing-KB$($Update.KBNumber)-setup.wim.log"
                        }
                        Write-Host "winpe.wim: $UpdateSSU"
                        if (Get-WindowsPackage -Path "$MountWinPE" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {
                            Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                        } else {
                            Add-WindowsPackage -Path "$MountWinPE" -PackagePath "$UpdateSSU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateServicing-KB$($Update.KBNumber)-winpe.wim.log"
                        }
                        Write-Host "winre.wim: $UpdateSSU"
                        if (Get-WindowsPackage -Path "$MountWinRE" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {
                            Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                        } else {
                            Add-WindowsPackage -Path "$MountWinRE" -PackagePath "$UpdateSSU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateServicing-KB$($Update.KBNumber)-winre.wim.log"
                        }
                    } else {
                        Write-Warning "Not Found: $UpdateSSU"
                    }
                }
            }
            #======================================================================================
            # WinPE Phase: Cumulative Update 18.9.13
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Cumulative Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateCumulative)) {
                foreach ($Update in $UpdateCumulative) {
                    $UpdateCU = $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
                    if (Test-Path "$UpdateCU") {
                        Write-Host "setup.wim: $UpdateCU"
                        #if (Get-WindowsPackage -Path "$MountSetup" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {}
                        $SessionsXmlSetup = "$MountSetup\Windows\Servicing\Sessions\Sessions.xml"
                        if (Test-Path $SessionsXmlSetup) {
                            [xml]$XmlDocument = Get-Content -Path $SessionsXmlSetup
                            if ($XmlDocument.Sessions.Session.Tasks.Phase.package | Where-Object {$_.Name -like "*$($Update.KBNumber)*" -and $_.targetState -eq 'Installed'}) {
                                Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                            } else {
                                Add-WindowsPackage -Path "$MountSetup" -PackagePath "$UpdateCU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-setup.wim.log"
                                Dism /Image:"$MountSetup" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image-setup.wim.log"
                            }
                        } else {
                            Add-WindowsPackage -Path "$MountSetup" -PackagePath "$UpdateCU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-setup.wim.log"
                            Dism /Image:"$MountSetup" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image-setup.wim.log"
                        }
                        Write-Host "winpe.wim: $UpdateCU"
                        #if (Get-WindowsPackage -Path "$MountWinPE" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {}
                        $SessionsXmlWinPE = "$MountWinPE\Windows\Servicing\Sessions\Sessions.xml"
                        if (Test-Path $SessionsXmlWinPE) {
                            [xml]$XmlDocument = Get-Content -Path $SessionsXmlWinPE
                            if ($XmlDocument.Sessions.Session.Tasks.Phase.package | Where-Object {$_.Name -like "*$($Update.KBNumber)*" -and $_.targetState -eq 'Installed'}) {
                                Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                            } else {
                                Add-WindowsPackage -Path "$MountWinPE" -PackagePath "$UpdateCU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-winpe.wim.log"
                                Dism /Image:"$MountWinPE" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image-winpe.wim.log"
                            }
                        } else {
                            Add-WindowsPackage -Path "$MountWinPE" -PackagePath "$UpdateCU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-winpe.wim.log"
                            Dism /Image:"$MountWinPE" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image-winpe.wim.log"
                        }
                        Write-Host "winre.wim: $UpdateCU"
                        #if (Get-WindowsPackage -Path "$MountWinRE" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {}
                        $SessionsXmlWinRE = "$MountWinRE\Windows\Servicing\Sessions\Sessions.xml"
                        if (Test-Path $SessionsXmlWinRE) {
                            [xml]$XmlDocument = Get-Content -Path $SessionsXmlWinRE
                            if ($XmlDocument.Sessions.Session.Tasks.Phase.package | Where-Object {$_.Name -like "*$($Update.KBNumber)*" -and $_.targetState -eq 'Installed'}) {
                                Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                            } else {
                                Add-WindowsPackage -Path "$MountWinRE" -PackagePath "$UpdateCU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-winre.wim.log"
                                Dism /Image:"$MountWinRE" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image-winre.wim.log"
                            }
                        } else {
                            Add-WindowsPackage -Path "$MountWinRE" -PackagePath "$UpdateCU" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-winre.wim.log"
                            Dism /Image:"$MountWinRE" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image-winre.wim.log"
                        }
                    } else {
                        Write-Warning "Not Found: $UpdateCU"
                    }
                }
            }
            #======================================================================================
            # WinPE Phase: WinPE Update Sources 18.9.10
            #======================================================================================
<# Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Updating OS Sources" -ForegroundColor Yellow
            robocopy "$MountSetup" "$OS" setup.exe /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Setup-setup.wim.log"
            robocopy "$MountSetup\sources" "$OS\sources" *.* /e /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Sources-setup.wim.log"
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Updating Setup.wim Sources" -ForegroundColor Yellow
            robocopy "$OS" "$MountSetup" setup.exe /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Setup-osmedia.log"
            robocopy "$OS\sources" "$MountSetup\sources" *.* /e /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Sources-osmedia.log" #>

            #======================================================================================
            # WinPE Mounted Package Inventory 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Exporting Package Inventory" -ForegroundColor Yellow
            Write-Host "$PEInfo\setup-WindowsPackage.txt"
            $GetWindowsPackage = Get-WindowsPackage -Path "$MountSetup"
            $GetWindowsPackage | Out-File "$PEInfo\setup-WindowsPackage.txt"
            $GetWindowsPackage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-setup.wim.txt"
            $GetWindowsPackage | Export-Clixml -Path "$PELogsXML\Get-WindowsPackage-setup.wim.xml"
            $GetWindowsPackage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-setup.wim.xml"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsPackage-setup.wim.json"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-setup.wim.json"

            Write-Host "$PEInfo\winpe-WindowsPackage.txt"
            $GetWindowsPackage = Get-WindowsPackage -Path "$MountWinPE"
            $GetWindowsPackage | Out-File "$PEInfo\winpe-WindowsPackage.txt"
            $GetWindowsPackage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-winpe.wim.txt"
            $GetWindowsPackage | Export-Clixml -Path "$PELogsXML\Get-WindowsPackage-winpe.wim.xml"
            $GetWindowsPackage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-winpe.wim.xml"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsPackage-winpe.wim.json"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-winpe.wim.json"

            Write-Host "$PEInfo\winre-WindowsPackage.txt"
            $GetWindowsPackage = Get-WindowsPackage -Path "$MountWinRE"
            $GetWindowsPackage | Out-File "$PEInfo\winre-WindowsPackage.txt"
            $GetWindowsPackage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-winre.wim.txt"
            $GetWindowsPackage | Export-Clixml -Path "$PELogsXML\Get-WindowsPackage-winre.wim.xml"
            $GetWindowsPackage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-winre.wim.xml"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsPackage-winre.wim.json"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage-winre.wim.json"
            #======================================================================================
            # WinPE Dismount and Save 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Dismount and Save" -ForegroundColor Yellow
            Write-Host "setup.wim: Dismount and Save $MountSetup"
            Dismount-WindowsImage -Path "$MountSetup" -Save -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dismount-WindowsImage-setup.wim.log" | Out-Null
            Write-Host "winpe.wim: Dismount and Save $MountWinPE"
            Dismount-WindowsImage -Path "$MountWinPE" -Save -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dismount-WindowsImage-winpe.wim.log" | Out-Null
            Write-Host "winre.wim: Dismount and Save $MountWinRE"
            Dismount-WindowsImage -Path "$MountWinRE" -Save -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dismount-WindowsImage-winre.wim.log" | Out-Null
            #======================================================================================
            # Export WinPE 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Exporting WinPE WIMs" -ForegroundColor Yellow
            Write-Host "setup.wim: Exporting to $WinPE\setup.wim"
            Export-WindowsImage -SourceImagePath "$WimTemp\setup.wim" -SourceIndex 1 -DestinationImagePath "$WinPE\setup.wim" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Export-WindowsImage-setup.wim.log" | Out-Null
            Write-Host "winpe.wim: Exporting to $WinPE\winpe.wim"
            Export-WindowsImage -SourceImagePath "$WimTemp\winpe.wim" -SourceIndex 1 -DestinationImagePath "$WinPE\winpe.wim" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Export-WindowsImage-winpe.wim.log" | Out-Null
            Write-Host "winre.wim: Exporting to $WinPE\winre.wim"
            Export-WindowsImage -SourceImagePath "$WimTemp\winre.wim" -SourceIndex 1 -DestinationImagePath "$WinPE\winre.wim" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Export-WindowsImage-winre.wim.log" | Out-Null
            #======================================================================================
            # Rebuild Boot.wim 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "WinPE Phase: Rebuilding Boot.wim" -ForegroundColor Yellow
            Write-Host "Rebuilding updated Boot.wim Index 1 at $WinPE\boot.wim"
            Export-WindowsImage -SourceImagePath "$WimTemp\winpe.wim" -SourceIndex 1 -DestinationImagePath "$WinPE\boot.wim" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Export-WindowsImage-boot.wim.log" | Out-Null
            Write-Host "Rebuilding updated Boot.wim Index 2 at $WinPE\boot.wim Bootable"
            Export-WindowsImage -SourceImagePath "$WimTemp\setup.wim" -SourceIndex 1 -DestinationImagePath "$WinPE\boot.wim" -Setbootable -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Export-WindowsImage-boot.wim.log" | Out-Null
            Write-Host "Copying Boot.wim to $OS\sources\boot.wim"
            Copy-Item -Path "$WinPE\boot.wim" -Destination "$OS\sources\boot.wim" -Force | Out-Null
            #======================================================================================
            # Mount Install.wim 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Mounting Operating System" -ForegroundColor Yellow
            Write-Host $MountDirectory
            Mount-WindowsImage -ImagePath "$WimTemp\install.wim" -Index 1 -Path "$MountDirectory" -Optimize -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Mount-WindowsImage.log"
            #======================================================================================
            # Get Registry and UBR 18.9.20
            #======================================================================================
            reg LOAD 'HKLM\OSMedia' "$MountDirectory\Windows\System32\Config\SOFTWARE"
            $RegCurrentVersion = Get-ItemProperty -Path 'HKLM:\OSMedia\Microsoft\Windows NT\CurrentVersion'
            reg UNLOAD 'HKLM\OSMedia'

            $OSVersionNumber = $null
            $OSVersionNumber = $($RegCurrentVersion.ReleaseId)
            $RegCurrentVersionUBR = $($RegCurrentVersion.UBR)
            $UBR = "$OSBuild.$RegCurrentVersionUBR"
            #======================================================================================
            # Export RegCurrentVersion 18.9.20
            #======================================================================================
            $RegCurrentVersion | Out-File "$Info\CurrentVersion.txt"
            $RegCurrentVersion | Out-File "$WorkingPath\CurrentVersion.txt"
            $RegCurrentVersion | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-CurrentVersion.txt"
            $RegCurrentVersion | Export-Clixml -Path "$LogsXML\CurrentVersion.xml"
            $RegCurrentVersion | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-CurrentVersion.xml"
            $RegCurrentVersion | ConvertTo-Json | Out-File "$LogsJS\CurrentVersion.json"
            $RegCurrentVersion | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-CurrentVersion.json"
            #======================================================================================
            # Replace WinRE 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Replacing WinRE.wim" -ForegroundColor Yellow
            Write-Host "Removing existing $MountDirectory\Windows\System32\Recovery\winre.wim"
            if (Test-Path "$MountDirectory\Windows\System32\Recovery\winre.wim") {
                Remove-Item -Path "$MountDirectory\Windows\System32\Recovery\winre.wim" -Force
            }
            #======================================================================================
            Write-Host "Copying WinRE.wim to $MountDirectory\Windows\System32\Recovery\winre.wim"
            Copy-Item -Path "$WinPE\winre.wim" -Destination "$MountDirectory\Windows\System32\Recovery\winre.wim" -Force | Out-Null
            #======================================================================================
            Write-Host "Generating WinRE.wim info"
            $GetWindowsImage = Get-WindowsImage -ImagePath "$WinPE\winre.wim" -Index 1 | Select-Object -Property *
            $GetWindowsImage | Out-File "$PEInfo\winre.txt"
            (Get-Content "$PEInfo\winre.txt") | Where-Object {$_.Trim(" `t")} | Set-Content "$PEInfo\winre.txt"
            $GetWindowsImage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-winre.wim.txt"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\Get-WindowsImage-winre.wim.xml"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-winre.wim.xml"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsImage-winre.wim.json"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-winre.wim.json"
            #======================================================================================
            # Install.wim Servicing Update 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Servicing Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateServicing)) {
                foreach ($Update in $UpdateServicing) {
                    $UpdateSSU = $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
                    if (Test-Path "$UpdateSSU") {
                        Write-Host "install.wim: $UpdateSSU"
                        if (Get-WindowsPackage -Path "$MountDirectory" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {
                            Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                        } else {
                            Add-WindowsPackage -Path "$MountDirectory" -PackagePath "$UpdateSSU" -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateServicing-KB$($Update.KBNumber)-install.wim.log"
                        }
                    } else {
                        Write-Warning "Not Found: $UpdateSSU"
                    }
                }
            }
            #======================================================================================
            # Get UBR (Pre Windows Updates) 18.9.20
            #======================================================================================
<# $DismResults = Invoke-Expression "dism /Image:$MountDirectory /?"
            $UBRPre = "$((((($DismResults -match 'Image Version') -split ' ')[2]) -split '\.')[2]).$((((($DismResults -match 'Image Version') -split ' ')[2]) -split '\.')[3])" #>

            $UBRPre = $UBR
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Update Build Revision $UBRPre (Pre-Windows Updates)"    -ForegroundColor Yellow
            #======================================================================================
            # Install.wim Cumulative Update 18.9.13
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Cumulative Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateCumulative)) {
                foreach ($Update in $UpdateCumulative) {
                    $UpdateCU = $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
                    if (Test-Path "$UpdateCU") {
                        Write-Host "install.wim: $UpdateCU"
                        $SessionsXmlInstall = "$MountDirectory\Windows\Servicing\Sessions\Sessions.xml"
                        if (Test-Path $SessionsXmlInstall) {
                            [xml]$XmlDocument = Get-Content -Path $SessionsXmlInstall
                            if ($XmlDocument.Sessions.Session.Tasks.Phase.package | Where-Object {$_.Name -like "*$($Update.KBNumber)*" -and $_.targetState -eq 'Installed'}) {
                                Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                            } else {
                                Add-WindowsPackage -Path "$MountDirectory" -PackagePath "$UpdateCU" -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-install.wim.log"
                            }
                        } else {
                            Add-WindowsPackage -Path "$MountDirectory" -PackagePath "$UpdateCU" -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateCumulative-KB$($Update.KBNumber)-install.wim.log"
                        }
                    } else {
                        Write-Warning "Not Found: $UpdateCU"
                    }
                }
            }
            #======================================================================================
            # Get Registry and UBR 18.9.20
            #======================================================================================
            reg LOAD 'HKLM\OSMedia' "$MountDirectory\Windows\System32\Config\SOFTWARE"
            $RegCurrentVersion = Get-ItemProperty -Path 'HKLM:\OSMedia\Microsoft\Windows NT\CurrentVersion'
            reg UNLOAD 'HKLM\OSMedia'

            $OSVersionNumber = $null
            $OSVersionNumber = $($RegCurrentVersion.ReleaseId)
            $RegCurrentVersionUBR = $($RegCurrentVersion.UBR)
            $UBR = "$OSBuild.$RegCurrentVersionUBR"
            #======================================================================================
            # Export RegCurrentVersion 18.9.20
            #======================================================================================
            $RegCurrentVersion | Out-File "$Info\CurrentVersion.txt"
            $RegCurrentVersion | Out-File "$WorkingPath\CurrentVersion.txt"
            $RegCurrentVersion | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-CurrentVersion.txt"
            $RegCurrentVersion | Export-Clixml -Path "$LogsXML\CurrentVersion.xml"
            $RegCurrentVersion | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-CurrentVersion.xml"
            $RegCurrentVersion | ConvertTo-Json | Out-File "$LogsJS\CurrentVersion.json"
            $RegCurrentVersion | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-CurrentVersion.json"
            #======================================================================================
            # Get UBR (Post Windows Updates) 18.9.20
            #======================================================================================
<# $DismResults = Invoke-Expression "dism /Image:$MountDirectory /?"
            $UBR = "$((((($DismResults -match 'Image Version') -split ' ')[2]) -split '\.')[2]).$((((($DismResults -match 'Image Version') -split ' ')[2]) -split '\.')[3])" #>

            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Update Build Revision $UBR (Post-Windows Updates)"    -ForegroundColor Yellow
            #======================================================================================
            # Install.wim Component Update 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Component Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateComponent)) {
                foreach ($Update in $UpdateComponent) {
                    $UpdateComp = $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
                    if (Test-Path "$UpdateComp") {
                        Write-Host "install.wim: $UpdateComp"
                        if (Get-WindowsPackage -Path "$MountDirectory" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {
                            Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                        } else {
                            Add-WindowsPackage -Path "$MountDirectory" -PackagePath "$UpdateComp" -LogPath "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateComponent-KB$($Update.KBNumber)-install.wim.log"
                        }
                    } else {
                        Write-Warning "Not Found: $UpdateComp"
                    }
                }
            }
            #======================================================================================
            # Install.wim Adobe Update 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Adobe Update" -ForegroundColor Yellow
            if (!($null -eq $UpdateAdobe)) {
                foreach ($Update in $UpdateAdobe) {
                    $UpdateA = $(Get-ChildItem -Path $UpdatesPath -Directory -Recurse | Where-Object {$_.Name -eq $($Update.KBTitle)}).FullName
                    if (Test-Path "$UpdateA") {
                        Write-Host "install.wim: $UpdateA"
                        if (Get-WindowsPackage -Path "$MountDirectory" | Where-Object {$_.PackageName -like "*$($Update.KBNumber)*"}) {
                            Write-Warning "KB$($Update.KBNumber) Installed ... Skipping Update"
                        } else {
                            Add-WindowsPackage -Path "$MountDirectory" -PackagePath "$UpdateA" -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-UpdateAdobe-KB$($Update.KBNumber)-install.wim.log"
                        }
                    } else {
                        Write-Warning "Not Found: $UpdateA"
                    }
                }
            }
            #======================================================================================
            # Install.wim Image Cleanup 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Windows Image Cleanup" -ForegroundColor Yellow
            if ($(Get-WindowsCapability -Path $MountDirectory | Where-Object {$_.state -eq "*pending*"})) {
                Write-Warning "Cannot run WindowsImage Cleanup on a WIM with Pending Installations"
            } else {
                Write-Host "Performing Image Cleanup on $MountDirectory"
                Dism /Image:"$MountDirectory" /Cleanup-Image /StartComponentCleanup /ResetBase /LogPath:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dism-Cleanup-Image.log"
            }
            #======================================================================================
            # Install.wim Update Media Sources 18.9.10
            #======================================================================================
<# Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Updating OS Sources" -ForegroundColor Yellow
            robocopy "$MountDirectory\Windows\System32" "$OS\sources" *.* /e /ndl /xo /xx /xl /b /np /ts /tee /r:0 /w:0 /log:"$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Robocopy-Sources-install.wim.log" #>

            #======================================================================================
            # Install.wim Save Mounted Windows Image Configuration 18.9.10
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Saving Mounted Windows Image Configuration" -ForegroundColor Yellow
            #======================================================================================
            if ($MediaName -notlike "*server*") {
                Write-Host "$WorkingPath\AppxProvisionedPackage.txt"
                $GetAppxProvisionedPackage = Get-AppxProvisionedPackage -Path "$MountDirectory"
                $GetAppxProvisionedPackage | Out-File "$Info\Get-AppxProvisionedPackage.txt"
                $GetAppxProvisionedPackage | Out-File "$WorkingPath\AppxProvisionedPackage.txt"
                $GetAppxProvisionedPackage | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-AppxProvisionedPackage.txt"
                $GetAppxProvisionedPackage | Export-Clixml -Path "$LogsXML\Get-AppxProvisionedPackage.xml"
                $GetAppxProvisionedPackage | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-AppxProvisionedPackage.xml"
                $GetAppxProvisionedPackage | ConvertTo-Json | Out-File "$LogsJS\Get-AppxProvisionedPackage.json"
                $GetAppxProvisionedPackage | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-AppxProvisionedPackage.json"
            }
            Write-Host "$WorkingPath\WindowsOptionalFeature.txt"
            $GetWindowsOptionalFeature = Get-WindowsOptionalFeature -Path "$MountDirectory"
            $GetWindowsOptionalFeature | Out-File "$Info\Get-WindowsOptionalFeature.txt"
            $GetWindowsOptionalFeature | Out-File "$WorkingPath\WindowsOptionalFeature.txt"
            $GetWindowsOptionalFeature | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsOptionalFeature.txt"
            $GetWindowsOptionalFeature | Export-Clixml -Path "$LogsXML\Get-WindowsOptionalFeature.xml"
            $GetWindowsOptionalFeature | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsOptionalFeature.xml"
            $GetWindowsOptionalFeature | ConvertTo-Json | Out-File "$LogsJS\Get-WindowsOptionalFeature.json"
            $GetWindowsOptionalFeature | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsOptionalFeature.json"

            Write-Host "$WorkingPath\WindowsCapability.txt"
            $GetWindowsCapability = Get-WindowsCapability -Path "$MountDirectory"
            $GetWindowsCapability | Out-File "$Info\Get-WindowsCapability.txt"
            $GetWindowsCapability | Out-File "$WorkingPath\WindowsCapability.txt"
            $GetWindowsCapability | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsCapability.txt"
            $GetWindowsCapability | Export-Clixml -Path "$LogsXML\Get-WindowsCapability.xml"
            $GetWindowsCapability | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsCapability.xml"
            $GetWindowsCapability | ConvertTo-Json | Out-File "$LogsJS\Get-WindowsCapability.json"
            $GetWindowsCapability | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsCapability.json"

            Write-Host "$WorkingPath\WindowsPackage.txt"
            $GetWindowsPackage = Get-WindowsPackage -Path "$MountDirectory"
            $GetWindowsPackage | Out-File "$Info\Get-WindowsPackage.txt"
            $GetWindowsPackage | Out-File "$WorkingPath\WindowsPackage.txt"
            $GetWindowsPackage | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage.txt"
            $GetWindowsPackage | Export-Clixml -Path "$LogsXML\Get-WindowsPackage.xml"
            $GetWindowsPackage | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage.xml"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$LogsJS\Get-WindowsPackage.json"
            $GetWindowsPackage | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsPackage.json"
            #======================================================================================
            # Dismount and Save
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Dismount and Save" -ForegroundColor Yellow
            Write-Host "Dismount and Save $MountDirectory"
            Dismount-WindowsImage -Path "$MountDirectory" -Save -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Dismount-WindowsImage.log"
            #======================================================================================
            # Export Install.wim
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Install.wim Phase: Export Install.wim" -ForegroundColor Yellow
            Write-Host "Exporting $WimTemp\install.wim"
            Export-WindowsImage -SourceImagePath "$WimTemp\install.wim" -SourceIndex 1 -DestinationImagePath "$OS\sources\install.wim" -LogPath "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Export-WindowsImage.log"
            #======================================================================================
            # Saving WinPE Image Configuration
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Inventory Phase: Saving WinPE Image Configuration" -ForegroundColor Yellow
            #======================================================================================
            # Get-WindowsImage Boot.wim
            #======================================================================================
            Write-Host "$PEInfo\boot.txt"
            $GetWindowsImage = Get-WindowsImage -ImagePath "$OS\sources\boot.wim"
            $GetWindowsImage | Out-File "$PEInfo\boot.txt"
            (Get-Content "$PEInfo\boot.txt") | Where-Object {$_.Trim(" `t")} | Set-Content "$PEInfo\boot.txt"
            $GetWindowsImage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-boot.wim.txt"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\Get-WindowsImage-boot.wim.xml"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-boot.wim.xml"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsImage-boot.wim.json"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-boot.wim.json"
            #======================================================================================
            # Get-WindowsImage WinPE
            #======================================================================================
            Write-Host "$PEInfo\winpe.txt"
            $GetWindowsImage = Get-WindowsImage -ImagePath "$OS\sources\boot.wim" -Index 1 | Select-Object -Property *
            $GetWindowsImage | Out-File "$PEInfo\winpe.txt"
            (Get-Content "$PEInfo\winpe.txt") | Where-Object {$_.Trim(" `t")} | Set-Content "$PEInfo\winpe.txt"
            $GetWindowsImage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-winpe.wim.txt"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\Get-WindowsImage-winpe.wim.xml"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-winpe.wim.xml"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsImage-winpe.wim.json"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-winpe.wim.json"
            #======================================================================================
            # Get-WindowsImage Setup
            #======================================================================================
            Write-Host "$PEInfo\setup.txt"
            $GetWindowsImage = Get-WindowsImage -ImagePath "$OS\sources\boot.wim" -Index 2 | Select-Object -Property *
            $GetWindowsImage | Out-File "$PEInfo\setup.txt"
            (Get-Content "$PEInfo\setup.txt") | Where-Object {$_.Trim(" `t")} | Set-Content "$PEInfo\setup.txt"
            $GetWindowsImage | Out-File "$PELogs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-setup.wim.txt"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\Get-WindowsImage-setup.wim.xml"
            $GetWindowsImage | Export-Clixml -Path "$PELogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-setup.wim.xml"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\Get-WindowsImage-setup.wim.json"
            $GetWindowsImage | ConvertTo-Json | Out-File "$PELogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage-setup.wim.json"
            #======================================================================================
            # Saving Windows Image Configuration
            #======================================================================================
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Inventory Phase: Saving Windows Image Configuration" -ForegroundColor Yellow
            Write-Host "$WorkingPath\WindowsImage.txt"
            $GetWindowsImage = Get-WindowsImage -ImagePath "$OS\sources\install.wim" -Index 1 | Select-Object -Property *
            $GetWindowsImage | Add-Member -Type NoteProperty -Name "UBR" -Value $UBR
            $GetWindowsImage | Out-File "$WorkingPath\WindowsImage.txt"
            $GetWindowsImage | Out-File "$Logs\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage.txt"
            $GetWindowsImage | Export-Clixml -Path "$LogsXML\Get-WindowsImage.xml"
            $GetWindowsImage | Export-Clixml -Path "$LogsXML\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage.xml"
            $GetWindowsImage | ConvertTo-Json | Out-File "$LogsJS\Get-WindowsImage.json"
            $GetWindowsImage | ConvertTo-Json | Out-File "$LogsJS\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Get-WindowsImage.json"
            (Get-Content "$WorkingPath\WindowsImage.txt") | Where-Object {$_.Trim(" `t")} | Set-Content "$WorkingPath\WindowsImage.txt"
            #======================================================================================
            # Get-WindowsImageContent
            #======================================================================================
            Write-Host "$Info\Get-WindowsImageContent.txt"  
            Get-WindowsImageContent -ImagePath "$OS\Sources\install.wim" -Index 1 | Out-File "$Info\Get-WindowsImageContent.txt"
            #======================================================================================
            # Display OS Information
            #======================================================================================
            Show-OSInfo $WorkingPath
            #======================================================================================
            # Remove Temporary Files 18.9.13
            #======================================================================================
            if (Test-Path "$WimTemp") {Remove-Item -Path "$WimTemp" -Force -Recurse | Out-Null}
            if (Test-Path "$MountDirectory") {Remove-Item -Path "$MountDirectory" -Force -Recurse | Out-Null}
            if (Test-Path "$MountWinRE") {Remove-Item -Path "$MountWinRE" -Force -Recurse | Out-Null}
            if (Test-Path "$MountWinPE") {Remove-Item -Path "$MountWinPE" -Force -Recurse | Out-Null}
            if (Test-Path "$MountSetup") {Remove-Item -Path "$MountSetup" -Force -Recurse | Out-Null}
            #======================================================================================
            # UBR Validation 18.9.12
            #======================================================================================
            if ($UBRPre -eq $UBR) {
                Write-Host "===========================================================================" -ForegroundColor Yellow
                Write-Warning "The Update Build Revision did not change after Windows Updates"
                Write-Warning "There may have been an issue applying the Cumulative Update if this was not expected"
            }
            if (!($UBR)) {$UBR = $((Get-Date).ToString('mmss'))}
            #======================================================================================
            # Set New Name 18.9.12
            #======================================================================================
            $OSImageName = $($GetWindowsImage.ImageName)
            $OSImageName = $OSImageName -replace "Windows 10", "Win10"
            $OSImageName = $OSImageName -replace "Enterprise", "Ent"
            $OSImageName = $OSImageName -replace "Education", "Edu"
            $OSImageName = $OSImageName -replace " for ", " "
            $OSImageName = $OSImageName -replace "Workstations", "Wks"
            $OSImageName = $OSImageName -replace "Windows Server 2016", "Svr2016"
            $OSImageName = $OSImageName -replace "ServerStandardACore", "Std Core"
            $OSImageName = $OSImageName -replace "ServerDatacenterACore", "DC Core"
            $OSImageName = $OSImageName -replace "ServerStandardCore", "Std Core"
            $OSImageName = $OSImageName -replace "ServerDatacenterCore", "DC Core"
            $OSImageName = $OSImageName -replace "ServerStandard", "Std"
            $OSImageName = $OSImageName -replace "ServerDatacenter", "DC"
            $OSImageName = $OSImageName -replace "Standard", "Std"
            $OSImageName = $OSImageName -replace "Datacenter", "DC"
            $OSImageName = $OSImageName -replace 'Desktop Experience', 'DTE'
            $OSImageName = $OSImageName -replace '\(', ''
            $OSImageName = $OSImageName -replace '\)', ''

            $OSArchitecture = $($GetWindowsImage.Architecture)
            if ($OSArchitecture -eq 0) {$OSArchitecture = 'x86'}
            elseif ($OSArchitecture -eq 1) {$OSArchitecture = 'MIPS'}
            elseif ($OSArchitecture -eq 2) {$OSArchitecture = 'Alpha'}
            elseif ($OSArchitecture -eq 3) {$OSArchitecture = 'PowerPC'}
            elseif ($OSArchitecture -eq 6) {$OSArchitecture = 'ia64'}
            elseif ($OSArchitecture -eq 9) {$OSArchitecture = 'x64'}

            $OSBuild = $($GetWindowsImage.Build)
            $OSVersionNumber = $null
            if (Test-Path "$LogsXML\CurrentVersion.xml") {
                $RegCurrentVersion = Import-Clixml -Path "$LogsXML\CurrentVersion.xml"
                $OSVersionNumber = $($RegCurrentVersion.ReleaseId)
            } else {
                if ($OSBuild -eq 17134) {$OSVersionNumber = 1803}
                if ($OSBuild -eq 16299) {$OSVersionNumber = 1709}
                if ($OSBuild -eq 15063) {$OSVersionNumber = 1703}
                if ($OSBuild -eq 14393) {$OSVersionNumber = 1607}
                if ($OSBuild -eq 10240) {$OSVersionNumber = 1507}
            }

            $OSLanguages = $($GetWindowsImage.Languages)
            if ($null -eq $OSVersionNumber ) {
                Write-Host ""
                Write-Warning "OS Build $OSVersionNumber is not automatically recognized"
                Write-Warning "Check for an updated version of OSBuilder"
                Write-Host ""
                if ($BuildName -like "build*") {$BuildName = "$OSImageName $OSArchitecture"}
            } else {
                if ($BuildName -like "build*") {$BuildName = "$OSImageName $OSArchitecture $OSVersionNumber"}
                
            }
            $BuildName = "$BuildName $OSLanguages"
            if ($($OSLanguages.count) -eq 1) {$BuildName = $BuildName.replace(' en-US', '')}
            
            $NewWorkingPathName = "$BuildName $UBR"
            $NewWorkingPath = "$Script:OSMediaPath\$NewWorkingPathName"
            #======================================================================================
            # Rename Build Directory
            #======================================================================================
            if (Test-Path $NewWorkingPath) {
                Write-Host ""
                Write-Warning "Trying to rename the Build directory, but it already exists"
                Write-Warning "Appending the HHmm to the directory name"
                $NewWorkingPathName = "$NewWorkingPathName $((Get-Date).ToString('mmss'))"
            }
            Write-Host "===========================================================================" -ForegroundColor Yellow
            Write-Host "Closing Phase: Renaming ""$WorkingPath"" to ""$NewWorkingPathName""" -ForegroundColor Yellow
            Stop-Transcript
            Rename-Item -Path "$WorkingPath" -NewName "$NewWorkingPathName" -ErrorAction Stop
        }
        Write-Host "===========================================================================" -ForegroundColor Green
        Write-Host "Complete!" -ForegroundColor Green
        Write-Host "===========================================================================" -ForegroundColor Green
    }
}