MSPatchTuesdayHub.psm1
#Region '.\Private\Group-UpdateByProduct.ps1' 0 <# .SYNOPSIS Groups updates by operating system product. .DESCRIPTION This function groups updates by operating system product. The function takes an array of updates and an array of operating system names, and returns a hashtable where each key is an operating system name and each value is an array of updates that match that operating system. .PARAMETER AllUpdates An array of updates to group by operating system product. Each update object must have a 'Product' property that contains the name of the operating system product (e.g. "Windows 10 Enterprise"). .PARAMETER OSList An array of operating system names to group by. Each operating system name should be a string that matches the start of the operating system product name (e.g. "Windows 10"). .OUTPUTS System.Collections.Hashtable A hashtable where each key is an operating system name and each value is an array of updates that match that operating system. .EXAMPLE $allUpdates = @( @{ Product = "Windows 10 Enterprise" Title = "Cumulative Update for Windows 10 Version 21H1" KB = "KB5001330" ReleaseDate = "04/20/2021" Severity = "Critical" }, @{ Product = "Windows Server 2016" Title = "Security Update for Windows Server 2016" KB = "KB5003204" ReleaseDate = "05/11/2021" Severity = "Important" } ) $osList = @("Windows 10", "Windows Server") $groupedUpdates = Group-UpdateByProduct -AllUpdates $allUpdates -OSList $osList $groupedUpdates["Windows 10"] $groupedUpdates["Windows Server"] .NOTES Author: DrIOSx #> function Group-UpdateByProduct { param( [Parameter(Mandatory = $true)] [System.Collections.ArrayList]$AllUpdates, [string[]]$OSList ) $Updates = @{} foreach ($OS in $OSList) { $Updates[$OS] = $AllUpdates | Where-Object { $_.Product -like "$OS*" } } return $Updates } #EndRegion '.\Private\Group-UpdateByProduct.ps1' 61 #Region '.\Private\Read-FileContent.ps1' 0 <# .SYNOPSIS Reads the contents of a file and returns the content as a single string. .DESCRIPTION This function reads the contents of a file and returns the content as a single string. .PARAMETER FilePath The path to the file to read. .OUTPUTS System.String The contents of the file as a single string. .EXAMPLE $fileContent = Read-FileContent -FilePath "C:\example.txt" $fileContent .NOTES Author: DrIOSx #> function Read-FileContent { param( [string]$FilePath ) return (Get-Content -Path $FilePath -Raw) } #EndRegion '.\Private\Read-FileContent.ps1' 23 #Region '.\Private\Show-OSUpdateSection.ps1' 0 <# .SYNOPSIS Generates HTML code for displaying OS updates in a collapsible table format. .DESCRIPTION This function takes an array of OS update objects and generates HTML code to display them in a collapsible table format. .PARAMETER osUpdates An array of OS update objects. Each OS update object must have a 'Title' property and an 'Updates' property, where 'Updates' is an array of update objects with the following properties: - 'Article': The KB article number of the update. - 'Max Severity': The maximum severity of the update. - 'ArticleUrl': The URL of the KB article. - 'Download': The type of download (e.g. 'Security Update'). - 'Download Url': The URL of the download. - 'Release Date': The release date of the update. - 'Impact': The impact of the update. - 'Build Number': The build number of the update. - 'Details': A description of the update. - 'Details Url': The URL of the details page. .OUTPUTS System.String The generated HTML code for displaying the OS updates in a collapsible table format. .EXAMPLE $osUpdates = @( @{ Title = "Windows 10, version 21H1" Updates = @( @{ Article = "KB5001330" 'Max Severity' = "Critical" ArticleUrl = "https://support.microsoft.com/en-us/topic/kb5001330-cumulative-update-preview-for-windows-10-version-21h1-april-20-2021-57a87a06-64de-45e7-9d3b-6b8a58a00bc6" Download = "Security Update" 'Download Url' = "https://www.microsoft.com/download/details.aspx?id=12345" 'Release Date' = "04/20/2021" Impact = "Remote Code Execution" 'Build Number' = "19043.928" Details = "This update fixes a vulnerability in blah blah blah." 'Details Url' = "https://support.microsoft.com/en-us/topic/kb5001330-cumulative-update-preview-for-windows-10-version-21h1-april-20-2021-57a87a06-64de-45e7-9d3b-6b8a58a00bc6" } ) } ) Show-OSUpdateSection -osUpdates $osUpdates .NOTES Author: DrIOSx #> function Show-OSUpdateSection { param( $osUpdates ) $sectionHtml = "" foreach ($os in $osUpdates) { $sectionHtml += @" <h3>$($os.Title)</h3> "@ $groupedUpdates = $os.Updates | Group-Object -Property Article foreach ($group in $groupedUpdates) { $firstUpdate = $group.Group[0] $tableId = "table_" + (New-Guid).ToString() $arrowId = "arrow_" + (New-Guid).ToString() $sectionHtml += @" <h4 onclick='toggleTable("$tableId", "$arrowId")' style='cursor:pointer;'><span id='$arrowId' class='arrow'>▶</span><span class='kb-number'>KB$($group.Name)</span> - Max Severity: $($firstUpdate.'Max Severity') - <a href='$($firstUpdate.ArticleUrl)' target='_parent'>Article URL</a> | Type: $($firstUpdate.Download) - <a href='$($firstUpdate.'Download Url')' target='_parent'>Download URL</a></h4> <table id='$tableId' style='display:none;'> <tr> <th onclick='onHeaderClick("$tableId", 0)'>Release Date</th> <th onclick='onHeaderClick("$tableId", 1)'>Impact</th> <th onclick='onHeaderClick("$tableId", 2)'>Build Number</th> <th onclick='onHeaderClick("$tableId", 3)'>Details</th> <th onclick='onHeaderClick("$tableId", 4)'>Details URL</th> <th onclick='onHeaderClick("$tableId", 5)'>Base Score</th> </tr> "@ foreach ($update in $group.Group) { $sectionHtml += @" <tr> <td>$($update.'Release Date')</td> <td>$($update.Impact)</td> <td>$($update.'Build Number')</td> <td>$($update.Details)</td> <td><a href='$($update.'Details Url' -replace "(?<=https://)(.*)//", '$1/')' target='_parent'>Link</a></td> <td>$($update.'Base Score')</td> </tr> "@ } $sectionHtml += @" </table> "@ } } return $sectionHtml } #EndRegion '.\Private\Show-OSUpdateSection.ps1' 99 #Region '.\Public\Get-PatchTuesdayReport.ps1' 0 function Get-PatchTuesdayReport { <# .SYNOPSIS Generates a Patch Tuesday report HTML file based on a CSV input file. .DESCRIPTION The function generates an HTML report file with the latest Microsoft updates released on Patch Tuesday. The report file includes separate sections for client and server operating systems. To use this function, follow these steps: Go to the Microsoft Security Response Center website at https://msrc.microsoft.com/update-guide. Select the appropriate filters to display the updates you want to include in the report. For example, select the following options: Product: Windows Server 2022, Windows Server 2019, Windows Server 2016, Windows Server 2012 R2, Windows 11 Version 22H2 for x64-based Systems, Windows 10 Version 22H2 for x64-based Systems. Severity: Critical Release Date: Last 30 days Click on "Download all as CSV" to download the updates as a CSV file. The function will import the CSV file with the appropriate headers: Import-Csv -Path $Path -Header 'Release Date','Product','Platform','Impact','Max Severity','Article','ArticleUrl','Download','Download Url','Build Number','Details','Details Url','Base Score' Use the Get-PatchTuesdayReport function to generate the HTML report file. Future updates will include options to specify the parameters. .PARAMETER CsvPath The path to the CSV input file containing the Microsoft update information. .PARAMETER DateId A string value used to identify the date of the Patch Tuesday report. .PARAMETER LogoUrl A string value representing the URL of the logo to be displayed in the report. .PARAMETER ImportHeaderAs An array of strings representing the header row of the CSV input file. .PARAMETER OSList An array of strings representing the list of operating systems to include in the report. .EXAMPLE PS C:> Get-PatchTuesdayReport -CsvPath "C:\updates.csv" -DateId "2022-Oct" -LogoUrl "https://example.com/logo.png" -OSList @("Windows Server 2012 R2", "Windows Server 2016", "Windows Server 2019", "Windows Server 2022", "Windows 11", "Windows 10") This example generates a Patch Tuesday report for October 2022 with updates for Windows Server 2012 R2, Windows Server 2016, Windows Server 2019, Windows Server 2022, Windows 11, and Windows 10 operating systems. The report includes a logo displayed at the top of the report. .INPUTS None. .OUTPUTS A string value containing the HTML code for the Patch Tuesday report. .NOTES None. .LINK https://github.com/CriticalSolutionsNetwork/ADAuditTasks/wiki/Get-PatchTuesdayReport .LINK https://criticalsolutionsnetwork.github.io/ADAuditTasks/#Get-PatchTuesdayReport #> [CmdletBinding()] param( [ValidateNotNull()] [string]$CsvPath, [ValidateNotNull()] [string]$DateId, [string]$LogoUrl, [string[]]$ImportHeaderAs = @("Release Date", "Product", "Platform", "Impact", "Max Severity", "Article", "ArticleUrl", "Download", "Download Url", "Build Number", "Details", "Details Url", "Base Score"), [string[]]$OSList = @('Windows Server 2012 R2', 'Windows Server 2016', 'Windows Server 2019', 'Windows Server 2022', 'Windows 11', 'Windows 10') ) begin { $AllUpdates = Import-Csv -Path $CsvPath -Header $ImportHeaderAs $Updates = Group-UpdateByProduct -AllUpdates $AllUpdates -OSList $OSList # Read CSS, JavaScript, and HTML template $moduleBase = (Get-Module MSPATCHTUESDAYHUB).ModuleBase $assetsPath = Join-Path $moduleBase "assets" $cssContent = Read-FileContent -FilePath (Join-Path $assetsPath "styles.css") $jsContent = Read-FileContent -FilePath (Join-Path $assetsPath "scripts.js") $htmlTemplate = Read-FileContent -FilePath (Join-Path $assetsPath "template.html") # Replace placeholders in the HTML template with the CSS and JavaScript content $htmlTemplate = $htmlTemplate -replace '/\* CSS-PLACEHOLDER \*/', $cssContent $htmlTemplate = $htmlTemplate -replace '/\* JS-PLACEHOLDER \*/', $jsContent } Process { # Generate the report content using the HTML template $html = $htmlTemplate -replace "<!--LOGO-URL-PLACEHOLDER-->", $LogoUrl -replace "<!--DATE-ID-PLACEHOLDER-->", $DateId $clientOSList = @('Windows 11', 'Windows 10') $serverOSList = $OSList | Where-Object { $_ -notin $clientOSList } $clientUpdates = $clientOSList | ForEach-Object { @{ 'Title' = "$_ Updates"; 'Updates' = $Updates[$_] } } $serverUpdates = $serverOSList | ForEach-Object { @{ 'Title' = "$_ Updates"; 'Updates' = $Updates[$_] } } $clientUpdatesHtml = Show-OSUpdateSection $clientUpdates $serverUpdatesHtml = Show-OSUpdateSection $serverUpdates $html = $html -replace "<!--CLIENT-UPDATES-PLACEHOLDER-->", $clientUpdatesHtml $html = $html -replace "<!--SERVER-UPDATES-PLACEHOLDER-->", $serverUpdatesHtml } End { return $html } } #EndRegion '.\Public\Get-PatchTuesdayReport.ps1' 95 |