Get-OSBuilderUpdates.ps1

function Get-OSBuilderUpdates {
    [CmdletBinding()]
    Param (
        [switch]$CatalogUpdate,
        [switch]$Download,
        [string]$FilterByKeywords,
        [ValidateSet('Adobe','Component','Cumulative','Servicing','Setup')]
        [string]$FilterCategory,
        [ValidateSet('Windows 10','Windows Server 2016')]
        [string]$FilterOS,
        [ValidateSet('x64','x86')]
        [string]$FilterOSArch,
        [ValidateSet('1507','1511','1607','1703','1709','1803','1809')]
        [string]$FilterOSBuild,
        [switch]$HideDetails,
        [switch]$IseGridView,
        [string]$KBTitle,
        [switch]$RemoveSuperseded,
        [switch]$ShowDownloaded
    )
    #======================================================================================
    # Initialize OSBuilder 18.9.13
    #======================================================================================
    Get-OSBuilder -CreatePaths -HideDetails
    #======================================================================================
    # Remove Old Updates 18.9.13
    #======================================================================================
    if (Test-Path "$Script:ContentPath\UpdateStacks") {
        Write-Warning "Removing old Servicing Stacks at $Script:ContentPath\UpdateStacks"
        Remove-Item -Path "$Script:ContentPath\UpdateStacks" -Recurse -Force
        Write-Host ""
    }
    if (Test-Path "$Script:ContentPath\UpdateWindows") {
        Write-Warning "Removing old Windows Updates at $Script:ContentPath\UpdateWindows"
        Remove-Item -Path "$Script:ContentPath\UpdateWindows" -Recurse -Force
        Write-Host ""
    }
    #======================================================================================
    # Check for Updates 18.9.13
    #======================================================================================
    if ($CatalogUpdate.IsPresent) {
        Write-Warning "Downloading $CatalogXmlUrl"
        $statuscode = try {(Invoke-WebRequest -Uri $CatalogXmlUrl -UseBasicParsing -DisableKeepAlive).StatusCode}
        catch [Net.WebException]{[int]$_.Exception.Response.StatusCode}
        if (!($statuscode -eq "200")) {
            Write-Warning "Could not connect to $CatalogXmlUrl (Status Code: $statuscode) ..."
        } else {
            Invoke-WebRequest -Uri $CatalogXmlUrl -OutFile $CatalogXml
        }

        Write-Warning "Downloading $CatalogJsonUrl"
        $statuscode = try {(Invoke-WebRequest -Uri $CatalogJsonUrl -UseBasicParsing -DisableKeepAlive).StatusCode}
        catch [Net.WebException]{[int]$_.Exception.Response.StatusCode}
        if (!($statuscode -eq "200")) {
            Write-Warning "Could not connect to $CatalogJsonUrl (Status Code: $statuscode) ..."
        } else {
            Invoke-WebRequest -Uri $CatalogJsonUrl -OutFile $CatalogJson
        }
    }
    #======================================================================================
    # Validate Local Catalog.xml 18.9.13
    #======================================================================================
    if (!(Test-Path "$CatalogXml")) {
        Write-Warning "Could not find $CatalogXml"
        Write-Warning "Downloading $CatalogXmlUrl"
        $statuscode = try {(Invoke-WebRequest -Uri $CatalogXmlUrl -UseBasicParsing -DisableKeepAlive).StatusCode}
        catch [Net.WebException]{[int]$_.Exception.Response.StatusCode}
        if (!($statuscode -eq "200")) {
            Write-Warning "Could not connect to $CatalogXmlUrl (Status Code: $statuscode) ..."
        } else {
            Invoke-WebRequest -Uri $CatalogXmlUrl -OutFile $CatalogXml
        }
    }
    if (!(Test-Path "$CatalogXml")) {
        Write-Warning "Download of $CatalogXmlUrl to $CatalogXml failed"
        Write-Warning "You must manually add this file for OSBuilder Updates to work properly"
        Break
    }
    #======================================================================================
    # Validate Local Catalog.json 18.9.13
    #======================================================================================
    if (!(Test-Path "$CatalogJson")) {
        Write-Warning "Could not find $CatalogJson"
        Write-Warning "Downloading $CatalogJsonUrl"

        $statuscode = try {(Invoke-WebRequest -Uri $CatalogJsonUrl -UseBasicParsing -DisableKeepAlive).StatusCode}
        catch [Net.WebException]{[int]$_.Exception.Response.StatusCode}
        if (!($statuscode -eq "200")) {
            Write-Warning "Could not connect to $CatalogJsonUrl (Status Code: $statuscode) ..."
        } else {
            Invoke-WebRequest -Uri $CatalogJsonUrl -OutFile $CatalogJson
        }
    }
    if (!(Test-Path "$CatalogJson")) {
        Write-Warning "Download of $CatalogJsonUrl to $CatalogJson failed"
        Write-Warning "You must manually add this file for OSBuilder Updates to work properly"
        Break
    }
    #======================================================================================
    # 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
    }
    #======================================================================================
    # Get Existing Updates 18.9.13
    #======================================================================================
    if (Test-Path $Script:UpdatesPath) {
        $ExistingUpdates = @(Get-ChildItem -Path "$Script:UpdatesPath\*\*" -Directory)
    }
    #======================================================================================
    # Get Downloaded and Superseded Updates 18.9.13
    #======================================================================================
    $DownloadedUpdates = @()
    $SupersededUpdates = @()
    foreach ($Update in $ExistingUpdates) {
        if ($Catalog.KBTitle -NotContains $Update.Name) {
            $SupersededUpdates += $Update.Name
        } else {
            $DownloadedUpdates += $Update.Name
        }
    }
    #======================================================================================
    # Show Downloaded Updates 18.9.13
    #======================================================================================
    if ($ShowDownloaded.IsPresent) {
        if ($DownloadedUpdates) {
            Write-Host "Downloaded Updates" -ForegroundColor Yellow
            $DownloadedUpdates
            Write-Host ""
        }
    }
    #======================================================================================
    # Show Superseded Updates 18.9.13
    #======================================================================================
    if (!($HideDetails.IsPresent)) {
        if ($SupersededUpdates) {
            Write-Host "Superseded Updates can be removed with -RemoveSuperseded" -ForegroundColor Yellow
            $SupersededUpdates
            Write-Host ""
        }
    }
    #======================================================================================
    # Remove Superseded Updates 18.9.13
    #======================================================================================
    if ($RemoveSuperseded.IsPresent){
        foreach ($Update in $SupersededUpdates) {
            $RemoveUpdate = Get-ChildItem -Path "$Script:UpdatesPath\*\*" -Directory | Where-Object {$_.Name -eq $Update}
            Write-Warning "Removing $RemoveUpdate"
            Remove-Item -Path $RemoveUpdate -Recurse -Force
        }
        Write-Host ""
    }
    #======================================================================================
    # Show Available Updates 18.9.13
    #======================================================================================
<# $AvailableUpdates = @()
    foreach ($Update in $Catalog) {
        if ($ExistingUpdates.Name -NotContains $Update.KBTitle) {
            $AvailableUpdates += $Update.KBTitle
        }
    }
    if ($AvailableUpdates) {
        Write-Host "Available Updates that have not been downloaded" -ForegroundColor Yellow
        $AvailableUpdates
        Write-Host ""
    } #>

    #======================================================================================
    # Filter KBTitle 18.9.13
    #======================================================================================
    if ($KBTitle) {
        $Catalog = $Catalog | Where-Object {$_.KBTitle -like "*$KBTitle*"}
    } else {
        #======================================================================================
        # Filter Category 18.9.13
        #======================================================================================
        if ($FilterCategory -eq 'Adobe' -or $FilterByKeywords -like "*Adobe*") {$Catalog = $Catalog | Where-Object {$_.Category -like "*Adobe*"}}
        if ($FilterCategory -eq 'Component' -or $FilterByKeywords -like "*Component*") {$Catalog = $Catalog | Where-Object {$_.Category -like "*Component*"}}
        if ($FilterCategory -eq 'Cumulative' -or $FilterByKeywords -like "*Cumulative*") {$Catalog = $Catalog | Where-Object {$_.Category -like "*Cumulative*"}}
        if ($FilterCategory -eq 'Servicing' -or $FilterByKeywords -like "*Servicing*") {$Catalog = $Catalog | Where-Object {$_.Category -like "*Servicing*"}}
        if ($FilterCategory -eq 'Setup' -or $FilterByKeywords -like "*Setup*") {$Catalog = $Catalog | Where-Object {$_.Category -like "*Setup*"}}
        #======================================================================================
        # Filter OperatingSystem 18.9.13
        #======================================================================================
        if ($FilterOS -eq 'Windows 10' -or $FilterByKeywords -like "*10*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*Windows 10*"}}
        if ($FilterOS -eq 'Windows Server 2016' -or $FilterByKeywords -like "*Server*" -or $FilterByKeywords -like "*2016*") {
            $Catalog = $Catalog | Where-Object {$_.KBTitle -like "*Windows Server*"}
        }
        #======================================================================================
        # Filter OSArchitecure 18.9.13
        #======================================================================================
        if ($FilterOSArch -eq 'x64' -or $FilterByKeywords -like "*64*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*x64*"}}
        if ($FilterOSArch -eq 'x86' -or $FilterByKeywords -like "*32*" -or $FilterByKeywords -like "*86*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*x86*"}}
        #======================================================================================
        # Filter OSBuilder 18.9.13
        #======================================================================================
        if ($FilterOSBuild -eq '1507' -or $FilterByKeywords -like "*1507*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1507*"}}
        if ($FilterOSBuild -eq '1511' -or $FilterByKeywords -like "*1511*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1511*"}}
        if ($FilterOSBuild -eq '1607' -or $FilterByKeywords -like "*1607*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1607*"}}
        if ($FilterOSBuild -eq '1703' -or $FilterByKeywords -like "*1703*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1703*"}}
        if ($FilterOSBuild -eq '1709' -or $FilterByKeywords -like "*1709*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1709*"}}
        if ($FilterOSBuild -eq '1803' -or $FilterByKeywords -like "*1803*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1803*"}}
        if ($FilterOSBuild -eq '1809' -or $FilterByKeywords -like "*1809*") {$Catalog = $Catalog | Where-Object {$_.KBTitle -like "*1809*"}}
        #======================================================================================
        # Select Updates with PowerShell ISE 18.9.13
        #======================================================================================
        if ($IseGridView.IsPresent) {$Catalog = $Catalog | Out-GridView -PassThru -Title 'Select Updates to Download and press OK'}
        #======================================================================================
        # Filtered Updates 18.9.13
        #======================================================================================
        $FilteredUpdates = @()
        foreach ($Update in $Catalog) {
            if ($ExistingUpdates.Name -NotContains $Update.KBTitle) {
                $FilteredUpdates += $Update.KBTitle
            }
        }
        if (!($HideDetails.IsPresent)) {
            if ($FilteredUpdates) {
                Write-Host "Available Filtered Updates can be downloaded with the -Download parameter" -ForegroundColor Yellow
                $FilteredUpdates
                Write-Host ""
            }
        }
    }
    #======================================================================================
    # Download Updates 18.9.13
    #======================================================================================
    if ($Download.IsPresent) {
        foreach ($Update in $Catalog) {
            $DownloadPath = "$Script:UpdatesPath\$($Update.Category)\$($Update.KBTitle)"
            $DownloadFullPath = "$DownloadPath\$($Update.FileName)"

            if (!(Test-Path $DownloadPath)) {New-Item -Path "$DownloadPath" -ItemType Directory -Force | Out-Null}
            if (!(Test-Path $DownloadFullPath)) {
                Write-Host "Downloading: $($Update.URL)" -ForegroundColor Yellow
                Start-BitsTransfer -Source $($Update.URL) -Destination $DownloadFullPath
            } else {
                Write-Warning "Exists: $($Update.KBTitle)"
            }
        }
        Write-Host ""
    }
    if (!($HideDetails.IsPresent)) {
        #======================================================================================
        # Complete
        #======================================================================================
        Write-Host "Complete!" -ForegroundColor Green
    }
}