diff --git a/LatestUpdate/Private/Get-UpdateCumulative.ps1 b/LatestUpdate/Private/Get-UpdateCumulative.ps1 index 23523f1..47a5052 100644 --- a/LatestUpdate/Private/Get-UpdateCumulative.ps1 +++ b/LatestUpdate/Private/Get-UpdateCumulative.ps1 @@ -27,36 +27,22 @@ Function Get-UpdateCumulative { $BuildVersion = [regex]::Match($item.title, $rxB).Value $PSObject = [PSCustomObject] @{ Title = $item.title - ID = $item.id + ID = "KB{0}" -f ($item.id).Split(":")[2] Build = $BuildVersion + Revision = ($BuildVersion.Split(".")[1]) Updated = $item.updated } $updateList.Add($PSObject) | Out-Null } } - - # Filter and select the most current update - If ($updateList.Count -ge 1) { - $sortedUpdateList = New-Object -TypeName System.Collections.ArrayList - ForEach ($update in $updateList) { - $PSObject = [PSCustomObject] @{ - Title = $update.title - ID = "KB{0}" -f ($update.id).Split(":")[2] - Build = $update.Build.Split(".")[0] - Revision = [int]($update.Build.Split(".")[1]) - Updated = ([DateTime]::Parse($update.updated)) - } - $sortedUpdateList.Add($PSObject) | Out-Null - } - If ($Previous.IsPresent) { - Write-Verbose -Message "$($MyInvocation.MyCommand): selecting previous update" - $latestUpdate = $sortedUpdateList | Sort-Object -Property Revision -Descending | Select-Object -First 2 | Select-Object -Last 1 - } - Else { - $latestUpdate = $sortedUpdateList | Sort-Object -Property Revision -Descending | Select-Object -First 1 - } - Write-Verbose -Message "$($MyInvocation.MyCommand): selected item [$($latestUpdate.title)]" + $Skip = 0 + if($Previous.IsPresent) + { + Write-Verbose -Message "$($MyInvocation.MyCommand): selecting previous update" + $Skip = 1 } + $latestUpdate = $updateList | Sort-Object -Property Revision -Descending | Select-Object -First 1 -Skip $Skip + Write-Verbose -Message "$($MyInvocation.MyCommand): selected item [$($latestUpdate.title)]" # Return object to the pipeline Write-Output -InputObject $latestUpdate diff --git a/LatestUpdate/Public/Get-LatestCumulativeUpdate.ps1 b/LatestUpdate/Public/Get-LatestCumulativeUpdate.ps1 index 907e06c..4dfb0cd 100644 --- a/LatestUpdate/Public/Get-LatestCumulativeUpdate.ps1 +++ b/LatestUpdate/Public/Get-LatestCumulativeUpdate.ps1 @@ -39,18 +39,19 @@ Function Get-LatestCumulativeUpdate { [CmdletBinding(HelpUri = "https://docs.stealthpuppy.com/docs/latestupdate/usage/get-latest")] [Alias("Get-LatestUpdate")] Param ( - [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline, HelpMessage = "Windows OS name.")] + [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline, HelpMessage = "Windows OS name.", ParameterSetName = "Default")] [ValidateNotNullOrEmpty()] [ValidateScript( { $_ -in $script:resourceStrings.ParameterValues.Versions10 })] [Alias('OS')] [System.String] $OperatingSystem = $script:resourceStrings.ParameterValues.Versions10[0], - [Parameter(Mandatory = $False, Position = 1, HelpMessage = "Windows 10 Semi-annual Channel version number.")] + [Parameter(Mandatory = $False, Position = 1, HelpMessage = "Windows 10 Semi-annual Channel version number.", ParameterSetName = "Default")] [ValidateScript( { $_ -in $script:resourceStrings.ParameterValues.Windows10Versions })] [System.String[]] $Version = $script:resourceStrings.ParameterValues.Windows10Versions[0], - - [Parameter(Mandatory = $False)] - [System.Management.Automation.SwitchParameter] $Previous + [Parameter(Mandatory = $False, ParameterSetName = "Default")] + [System.Management.Automation.SwitchParameter] $Previous, + [Parameter(Mandatory = $False, Position = 0, HelpMessage = "Build Number", ParameterSetName = "Build")] + [int]$Build ) # If resource strings are returned we can continue @@ -59,20 +60,29 @@ Function Get-LatestCumulativeUpdate { # Get the update feed and continue if successfully read Write-Verbose -Message "$($MyInvocation.MyCommand): get feed for $OperatingSystem." $updateFeed = Get-UpdateFeed -Uri $script:resourceStrings.UpdateFeeds.Windows10 + $updateList = New-Object -TypeName System.Collections.ArrayList + + if($Build) + { + $BuildList = @($Build) + } + else + { + $BuildList = $Version | ForEach-Object { $script:resourceStrings.VersionTable.Windows10Builds[$_] } + } If ($Null -ne $updateFeed) { - ForEach ($ver in $Version) { + ForEach ($Build in $BuildList) { # Filter the feed for cumulative updates and continue if we get updates - Write-Verbose -Message "$($MyInvocation.MyCommand): search feed for version $ver." + Write-Verbose -Message "$($MyInvocation.MyCommand): search feed for build $Build." $gucParams = @{ UpdateFeed = $updateFeed - Build = $script:resourceStrings.VersionTable.Windows10Builds[$ver] + Build = $Build } If ($Previous.IsPresent) { $gucParams.Previous = $True } - $updateList = Get-UpdateCumulative @gucParams + $updateList.AddRange(@(Get-UpdateCumulative @gucParams)) Write-Verbose -Message "$($MyInvocation.MyCommand): update count is: $($updateList.Count)." - If ($Null -ne $updateList) { # Get download info for each update from the catalog @@ -84,7 +94,7 @@ Function Get-LatestCumulativeUpdate { $downloadInfo = Get-UpdateCatalogDownloadInfo @downloadInfoParams # Add the Version and Architecture properties to the list - $downloadInfo | Add-Member -NotePropertyName "Version" -NotePropertyValue $ver + $downloadInfo | Add-Member -NotePropertyName "Build" -NotePropertyValue $Build $updateListWithArchParams = @{ InputObject = $downloadInfo Property = "Note" @@ -93,8 +103,22 @@ Function Get-LatestCumulativeUpdate { } $updateListWithArch = Add-Property @updateListWithArchParams + $updateListWithArchParams = @{ + InputObject = $downloadInfo + Property = "Note" + NewPropertyName = "Version" + MatchPattern = $script:resourceStrings.Matches.Windows10Version + } + $updateListWithArch = Add-Property @updateListWithArchParams + # Add Revsion property - $updateListWithArch | Add-Member -NotePropertyName "Revision" -NotePropertyValue "$($updateList.Build).$($updateList.Revision)" + $updateListWithArch | Add-Member -NotePropertyName "Revision" -NotePropertyValue $updateList.Revision + + # Remove updates where description version doesn't match specified version + if($null -ne $Version) + { + $updateListWithArch = $updateListWithArch | Where-Object { $_.Version -in $Version } + } # Return object to the pipeline If ($Null -ne $updateListWithArch) { diff --git a/README.md b/README.md index 53ddf75..267fe13 100644 --- a/README.md +++ b/README.md @@ -14,18 +14,26 @@ A module for retrieving the latest Windows 10 / Windows Server 2016, 2019, Semi- Importing a cumulative update into [the Packages nodes in an MDT share](https://docs.microsoft.com/en-us/sccm/mdt/use-the-mdt#ConfiguringPackagesintheDeploymentWorkbench) enables updates during the offline phase of Windows setup, speeding up an installation of Windows. Updates can also be [applied directly to a WIM](https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/dism-operating-system-package-servicing-command-line-options). -## Documentation +### Documentation Regularly updated documentation for the module is located at [https://docs.stealthpuppy.com/docs/latestupdate/](https://docs.stealthpuppy.com/docs/latestupdate/) -## Supported Platforms +### Supported Platforms LatestUpdate supports PowerShell 5.0 and above and is tested on macOS, Windows 10 and Windows Server 2016. Some basic testing has been done on Windows 7 with WMF 5.1. If you are running an earlier version of PowerShell, update to the latest release of the [Windows Management Framework](https://docs.microsoft.com/en-us/skypeforbusiness/set-up-your-computer-for-windows-powershell/download-and-install-windows-powershell-5-1). -### PowerShell Core +#### PowerShell Core Verison 3 of `LatestUpdate` has been re-written and includes full support for PowerShell Core. +### PowerShell Gallery + +The VcRedist module is published to the PowerShell Gallery and can be found here: [LatestUpdate](https://www.powershellgallery.com/packages/LatestUpdate/). Install the module from the gallery with: + +```powershell +Install-Module -Name LatestUpdate -Force +``` + ## Acknowledgements This module uses code and inspiration from these sources: @@ -33,8 +41,8 @@ This module uses code and inspiration from these sources: * [Keith Garner](https://twitter.com/keithga1) - [gist](https://gist.github.com/keithga/1ad0abd1f7ba6e2f8aff63d94ab03048) * [Nickolaj Andersen](https://twitter.com/NickolajA) - [script](https://github.com/SCConfigMgr/ConfigMgr/blob/master/Software%20Updates/Invoke-MSLatestUpdateDownload.ps1) -[appveyor-badge]: https://ci.appveyor.com/api/projects/status/s4g24puifpegq7kf/branch/master?svg=true&failingText=master%20-%20failing&passingText=master%20-%20OK&logo=PowerShell&style=flat-square -[appveyor-badge-dev]: https://ci.appveyor.com/api/projects/status/s4g24puifpegq7kf/branch/development?svg=true&failingText=development%20-%20failing&passingText=development%20-%20OK&logo=PowerShell&style=flat-square +[appveyor-badge]: https://img.shields.io/appveyor/ci/aaronparker/LatestUpdate/master.svg?style=flat-square&logo=appveyor&label=master +[appveyor-badge-dev]: https://img.shields.io/appveyor/ci/aaronparker/LatestUpdate/development.svg?style=flat-square&logo=appveyor&label=development [appveyor-build]: https://ci.appveyor.com/project/aaronparker/latestupdate/ [psgallery-badge]: https://img.shields.io/powershellgallery/dt/latestupdate.svg?logo=PowerShell&style=flat-square [psgallery]: https://www.powershellgallery.com/packages/latestupdate