Private/Get-UpdateDownloadArray.ps1
Function Get-UpdateDownloadArray { <# .SYNOPSIS Constructs a table with KB article, Update Id number and Update description from provided HTML links .NOTES Author: Aaron Parker Twitter: @stealthpuppy .PARAMETER Links An object containing links filtered from a HTML object. #> [CmdletBinding()] Param ( [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True)] [ValidateNotNullOrEmpty()] [PSCustomObject] $IdTable ) # Search strings [string] $win10 = "Windows 10.*" [string] $rxArch = "\s+([a-zA-Z0-9]+)-based" [regex] $rx10 = "([1-2][0-9][0-1][0-9])\s" $editions = @{ "Windows Server 2019" = "1809" "Windows Server 2016" = "1607" "Windows Server 2012 R2" = "2012 R2" "Windows Server 2012(?!\sR2)" = "2012" "Windows Server 2008 R2" = "2008R2" "Windows 8.1" = "8.1" "Windows Embedded 8 Standard" = "8Embedded" "Windows 7" = "7" "Windows Embedded Standard 7" = "7Embedded" } $architectures = @{ "Windows Server 2019" = "x64" "Windows Server 2016" = "x64" "Windows Server 2012 R2" = "x64" "Windows Server 2012(?!\sR2)" = "x64" "Windows Server 2008 R2" = "x64" "Windows 8.1" = "x86" "Windows Embedded 8 Standard" = "x86" "Windows 7" = "x86" "Windows Embedded Standard 7" = "x86" } $output = @() ForEach ($idItem in $IdTable) { try { Write-Verbose -Message "Checking Microsoft Update Catalog for Id: $($idItem.id)." $post = @{ size = 0; updateID = $idItem.id; uidInfo = $idItem.id } | ConvertTo-Json -Compress $postBody = @{ updateIDs = "[$post]" } $url = Invoke-WebRequest -Uri 'http://www.catalog.update.microsoft.com/DownloadDialog.aspx' ` -Method Post -Body $postBody -UseBasicParsing -ErrorAction SilentlyContinue | ` Select-Object -ExpandProperty Content | ` Select-String -AllMatches -Pattern "(http[s]?\://download\.windowsupdate\.com\/[^\'\""]*)" | ` ForEach-Object { $_.matches.value } } catch { Throw "Failed to parse Microsoft Update Catalog for Id: $($idItem.id)." Break } finally { Write-Verbose -Message "Adding $url to output." $newItem = New-Object PSCustomObject $newItem | Add-Member -type NoteProperty -Name 'KB' -Value $idItem.KB # Add custom version note and check architecture based on description returned from page $arch = Get-RxString -String $idItem.Note -RegEx $rxArch If ($idItem.Note -match $win10) { $version = Get-RxString -String $idItem.Note -RegEx $rx10 If ($Null -eq $arch) { $arch = "x86" } } Else { ForEach ($key in $editions.Keys) { If ($idItem.Note -match ([regex] $key)) { Write-Verbose "Matched: $key" $version = $editions[$key] If ($Null -eq $arch) { $arch = $architectures[$key] } } } } $newItem | Add-Member -type NoteProperty -Name 'Arch' -Value $arch $newItem | Add-Member -type NoteProperty -Name 'Version' -Value $version $newItem | Add-Member -type NoteProperty -Name 'Note' -Value $idItem.Note # Filter URL to ensure only .MSU updates are returned If (Test-PSCore) { $download = $url | Where-Object { (Split-Path -Path $_ -Extension) -match ".msu" } } Else { $download = $url | Where-Object { ([IO.Path]::GetExtension($_)) -match ".msu" } } $newItem | Add-Member -type NoteProperty -Name 'URL' -Value $download # Add item to the output array $output += $newItem } } Write-Output $output } |