Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Feature "Include Details from Microsoft Update Catalog". #39

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 86 additions & 1 deletion MSCatalog/Classes/MSCatalogUpdate.Class.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,89 @@ class MSCatalogUpdate {
}
}
}
}
}


class MSCatalogUpdateWithDetails : MSCatalogUpdate {

[string] $UpdateId
[string] $Description
[string] $Architecture
[string] $Classification
[string] $SupportedProducts
[string] $SupportedLanguages
[string] $MsrcNumber
[string] $MsrcSeverity
[string] $KbArticle
[string] $MoreInformationUrl
[string] $SupportUrl
[PSCustomObject[]] $SupersededBy
[PSCustomObject[]] $Supersedes
[string] $RestartBehavior
[string] $UserInput
[string] $Exclusive
[string] $RequiresNetwork
[string] $UninstallNotes
[string] $UninstallSteps

MSCatalogUpdateWithDetails($Row, $IncludeFileNames) : base($Row, $IncludeFileNames) {
$HtmlDocs = Invoke-CatalogItemDetails($this.Guid)

## Overview Section
$HtmlDocOverview = $HtmlDocs["Overview"]
$this.UpdateId = $HtmlDocOverview.GetElementbyId("ScopedViewHandler_UpdateID").InnerText.Trim()
$this.Description = $HtmlDocOverview.GetElementbyId("ScopedViewHandler_desc").InnerText.Trim()
$this.Architecture = $HtmlDocOverview.GetElementbyId("archDiv").ChildNodes[2].InnerText.Trim()
$this.Classification = $HtmlDocOverview.GetElementbyId("classificationDiv").ChildNodes[2].InnerText.Trim()
$this.SupportedProducts = $HtmlDocOverview.GetElementbyId("productsDiv").ChildNodes[2].InnerText.Trim() -replace '\s(?=\s|,)','' #removes whitespaces followed by whitspaces or commas.
$this.SupportedLanguages = $HtmlDocOverview.GetElementbyId("languagesDiv").ChildNodes[2].InnerText.Trim() -replace '\s(?=\s|,)',''
$this.MsrcNumber = $HtmlDocOverview.GetElementbyId("securityBullitenDiv").ChildNodes[2].InnerText.Trim()
$this.MsrcSeverity = $HtmlDocOverview.GetElementbyId("ScopedViewHandler_msrcSeverity").InnerText.Trim()
$this.KbArticle = $HtmlDocOverview.GetElementbyId("kbDiv").ChildNodes[2].InnerText.Trim()
$this.MoreInformationUrl = $HtmlDocOverview.GetElementbyId("moreInfoDiv").SelectNodes("div").InnerText.Trim()
$this.SupportUrl = $HtmlDocOverview.GetElementbyId("suportUrlDiv").SelectNodes("div").InnerText.Trim()

## Package Details Section
$HtmlDocDetails = $HtmlDocs["PackageDetails"]
$SupersededByBox = $HtmlDocDetails.GetElementbyId("supersededbyInfo").SelectNodes("div")
$this.SupersededBy = [MSCatalogItemReferenceList]::new($SupersededByBox).ItemReferenceList
$SupersedesBox = $HtmlDocDetails.GetElementbyId("supersedesInfo").SelectNodes("div")
$this.Supersedes = [MSCatalogItemReferenceList]::new($SupersedesBox).ItemReferenceList

## Install Details Section
$HtmlDocInstall = $HtmlDocs["InstallDetails"]
$this.RestartBehavior = $HtmlDocInstall.GetElementbyId("ScopedViewHandler_rebootBehavior").InnerText.Trim()
$this.UserInput = $HtmlDocInstall.GetElementbyId("ScopedViewHandler_userInput").InnerText.Trim()
$this.Exclusive = $HtmlDocInstall.GetElementbyId("ScopedViewHandler_installationImpact").InnerText.Trim()
$this.RequiresNetwork = $HtmlDocInstall.GetElementbyId("ScopedViewHandler_connectivity").InnerText.Trim()
$this.UninstallNotes = $HtmlDocInstall.GetElementbyId("uninstallNotesDiv").SelectNodes("div").InnerText.Trim()
$this.UninstallSteps = $HtmlDocInstall.GetElementbyId("uninstallStepsDiv").SelectNodes("div").InnerText.Trim()
}
}

class MSCatalogItemReferenceList {
[PSCustomObject[]] $ItemReferenceList = @()

MSCatalogItemReferenceList($InfoBox) {

foreach ($node in $InfoBox) {
$ItemReference = [PSCustomObject]@{
Name = $node.InnerText.Trim()
KbArticle = [string]::Empty
UpdateID = [string]::Empty
}

$ItemReference.KbArticle = if ($ItemReference.Name -match 'KB\d+'){
$Matches.0
}
$ItemReference.UpdateID = if ($node.SelectNodes("a").Count -eq 1) {

$href = $node.SelectNodes("a").GetAttributeValue("href", [string]::Empty)
if ($href.contains("updateid")) {
($href -split ("updateid="))[1].Trim()
}
}
$this.ItemReferenceList += $ItemReference
}
}
}
48 changes: 48 additions & 0 deletions MSCatalog/Private/Invoke-CatalogItemDetails.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

function Invoke-CatalogItemDetails {

[CmdletBinding()]
param (
[parameter(Mandatory = $true)]
[string] $UpdateId
)



$BaseUri = "https://www.catalog.update.microsoft.com/ScopedViewInline.aspx?updateid=$([uri]::EscapeDataString($UpdateId))"
$Tabs = @("Overview", "LanguageSelection", "PackageDetails", "InstallDetails")
$Params = @{
ContentType = "application/x-www-form-urlencoded"
UseBasicParsing = $true
ErrorAction = "Stop"
}
$HtmlDocs = @{}



foreach ($tab in $Tabs) {
try {
Set-TempSecurityProtocol

$response = Invoke-WebRequest -Uri $BaseUri+"#"+$tab @Params
$HtmlTab = [HtmlAgilityPack.HtmlDocument]::new()
$HtmlTab.LoadHtml($response.RawContent.ToString())

$CouldNotBeFound = $HtmlTab.GetElementbyId("ctl00_catalogBody_thanksNoUpdate")
if ($null -eq $CouldNotBeFound) {

$HtmlDocs[$tab] = $HtmlTab
}
else {
throw "Could not retrieve details for the Update with ID $UpdateId"
}

Set-TempSecurityProtocol -ResetToDefault
}catch {
throw $_
}
}

$HtmlDocs

}
16 changes: 15 additions & 1 deletion MSCatalog/Public/Get-MSCatalogUpdate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ function Get-MSCatalogUpdate {
.PARAMETER ExcludePreview
Exclude preview updates from the search results.

.PARAMETER IncludeDetails
Includes the details of the Updates, such as Description, Architecture, Classification, Supported products and languages, MSRC number, etc.

.PARAMETER AllPages
By default the Get-MSCatalogUpdate command returns the first page of results from catalog.update.micrsosoft.com, which is
limited to 25 updates. If you specify this switch the command will instead return all pages of search results.
Expand Down Expand Up @@ -69,6 +72,9 @@ function Get-MSCatalogUpdate {
[Parameter(Mandatory = $false)]
[switch] $ExcludePreview,

[Parameter(Mandatory = $false)]
[switch] $IncludeDetails,

[Parameter(Mandatory = $false)]
[switch] $AllPages
)
Expand Down Expand Up @@ -155,7 +161,15 @@ function Get-MSCatalogUpdate {
if ($Rows.Count -gt 0) {
foreach ($Row in $Rows) {
if ($Row.Id -ne "headerRow") {
[MSCatalogUpdate]::new($Row, $IncludeFileNames)
if ($IncludeDetails) {

Write-Progress -Activity "Parsing Updates from Catalog" -CurrentOperation $Row.Id
[MSCatalogUpdateWithDetails]::new($Row, $IncludeFileNames)
}
else {
[MSCatalogUpdate]::new($Row, $IncludeFileNames)
}

}
}
} else {
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ Get-MSCatalogUpdate -Search "Cumulative Update for Windows Server 2016 (1803)" -
**NOTE: This could cause a significant number of web requests. The catalog website will only provide 25 results at a time
and this would just keep looping over all available results until it reaches the maximum of 1000.**

In order to obtain more details for each patch, use the parameter `IncludeDetails`. For each search result, addtional details such as architecture, KB Article, MSRC references and supersedence information are parsed as well. Be aware that this increases the amount of requests by a factor of three. All details are avaible in the returned objects, but are not displayed by default.

```powershell
Get-MSCatalogUpdate -Search "Cumulative Update for Windows Server 2016 (1803)" -IncludeDetails
```


## Save-MSCatalogUpdate

This command is used to download update files from the [https://www.catalog.update.microsoft.com](https://www.catalog.update.microsoft.com)
Expand Down