-
-
Save SMSAgentSoftware/79fb091a4b7806378fc0daa826dbfb47 to your computer and use it in GitHub Desktop.
| [CmdletBinding()] | |
| Param( | |
| [switch]$ListAllAvailable, | |
| [switch]$ExcludePreview, | |
| [switch]$ExcludeOutofBand | |
| ) | |
| $ProgressPreference = 'SilentlyContinue' | |
| Function Get-MyWindowsVersion { | |
| [CmdletBinding()] | |
| Param | |
| ( | |
| $ComputerName = $env:COMPUTERNAME | |
| ) | |
| $Table = New-Object System.Data.DataTable | |
| $Table.Columns.AddRange(@("ComputerName","Windows edition","Version","Build number")) | |
| $ProductName = Get-CimInstance -ClassName Win32_OperatingSystem -Property Caption | Select -ExpandProperty Caption | |
| Try | |
| { | |
| $DisplayVersion = (Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name DisplayVersion -ErrorAction Stop) | |
| } | |
| Catch | |
| { | |
| $DisplayVersion = "N/A" | |
| } | |
| $CurrentBuild = Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name CurrentBuild | |
| $UBR = Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name UBR | |
| $OSVersion = $CurrentBuild + "." + $UBR | |
| $TempTable = New-Object System.Data.DataTable | |
| $TempTable.Columns.AddRange(@("ComputerName","Windows edition","Version","Build number")) | |
| [void]$TempTable.Rows.Add($env:COMPUTERNAME,$ProductName,$DisplayVersion,$OSVersion) | |
| Return $TempTable | |
| } | |
| Function Convert-ParsedArray { | |
| Param($Array) | |
| $ArrayList = New-Object System.Collections.ArrayList | |
| foreach ($item in $Array) | |
| { | |
| [void]$ArrayList.Add([PSCustomObject]@{ | |
| Update = $item.outerHTML.Split('>')[1].Replace('</a','').Replace('—',' - ') | |
| KB = "KB" + $item.href.Split('/')[-1] | |
| InfoURL = "https://support.microsoft.com" + $item.href | |
| OSBuild = [int]$item.outerHTML.Split('.')[-1].Split(')')[0] # Just for sorting | |
| }) | |
| } | |
| Return $ArrayList | |
| } | |
| # Get Windows info | |
| $CurrentWindowsVersion = Get-MyWindowsVersion -ErrorAction Stop | |
| # Set the correct URL for W11 or W10 | |
| If ($CurrentWindowsVersion.'Build number' -like "2*") | |
| { | |
| $URI = "https://aka.ms/Windows11UpdateHistory" | |
| } | |
| If ($CurrentWindowsVersion.'Build number' -like "1*") | |
| { | |
| $URI = "https://support.microsoft.com/en-gb/topic/windows-10-update-history-7dd3071a-3906-fa2c-c342-f7f86728a6e3" | |
| } | |
| # Retrieve the web pages | |
| If ($PSVersionTable.PSVersion.Major -ge 6) | |
| { | |
| $Response = Invoke-WebRequest -Uri $URI -ErrorAction Stop | |
| } | |
| else | |
| { | |
| $Response = Invoke-WebRequest -Uri $URI -UseBasicParsing -ErrorAction Stop | |
| } | |
| # Pull the version data from the HTML | |
| If (!($Response.Links)) | |
| { throw "Response was not parsed as HTML"} | |
| $VersionDataRaw = $Response.Links | where {$_.outerHTML -match "supLeftNavLink" -and $_.outerHTML -match "KB"} | |
| # Pull all the update info if requested | |
| If ($ListAllAvailable) | |
| { | |
| If ($ExcludePreview -and $ExcludeOutofBand) | |
| { | |
| $AllAvailable = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0] -and $_.outerHTML -notmatch "Preview" -and $_.outerHTML -notmatch "Out-of-band"} | |
| } | |
| ElseIf ($ExcludePreview) | |
| { | |
| $AllAvailable = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0] -and $_.outerHTML -notmatch "Preview"} | |
| } | |
| ElseIf ($ExcludeOutofBand) | |
| { | |
| $AllAvailable = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0] -and $_.outerHTML -notmatch "Out-of-band"} | |
| } | |
| Else | |
| { | |
| $AllAvailable = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0]} | |
| } | |
| $UniqueList = (Convert-ParsedArray -Array $AllAvailable) | Select -Property * -Unique | Sort OSBuild -Descending | |
| $Table = New-Object System.Data.DataTable | |
| [void]$Table.Columns.AddRange(@('Update','KB','InfoURL')) | |
| foreach ($Update in $UniqueList) | |
| { | |
| [void]$Table.Rows.Add( | |
| $Update.Update, | |
| $Update.KB, | |
| $Update.InfoURL | |
| ) | |
| } | |
| Return $Table | |
| } | |
| # Get the latest patch info | |
| $CurrentPatch = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'} | Select -First 1 | |
| If ($ExcludePreview -and $ExcludeOutofBand) | |
| { | |
| $LatestAvailablePatch = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0] -and $_.outerHTML -notmatch "Out-of-band" -and $_.outerHTML -notmatch "Preview"} | Select -First 1 | |
| } | |
| ElseIf ($ExcludePreview) | |
| { | |
| $LatestAvailablePatch = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0] -and $_.outerHTML -notmatch "Preview"} | Select -First 1 | |
| } | |
| ElseIf ($ExcludeOutofBand) | |
| { | |
| $LatestAvailablePatch = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0] -and $_.outerHTML -notmatch "Out-of-band"} | Select -First 1 | |
| } | |
| Else | |
| { | |
| $LatestAvailablePatch = $VersionDataRaw | where {$_.outerHTML -match $CurrentWindowsVersion.'Build number'.Split('.')[0]} | Select -First 1 | |
| } | |
| # Add the data to a table | |
| $Table = New-Object System.Data.DataTable | |
| [void]$Table.Columns.AddRange(@('OSVersion','OSEdition','OSBuild','CurrentInstalledUpdate','CurrentInstalledUpdateKB','CurrentInstalledUpdateInfoURL','LatestAvailableUpdate','LastestAvailableUpdateKB','LastestAvailableUpdateInfoURL')) | |
| [void]$Table.Rows.Add( | |
| $CurrentWindowsVersion.Version, | |
| $CurrentWindowsVersion.'Windows edition', | |
| $CurrentWindowsVersion.'Build number', | |
| $CurrentPatch.outerHTML.Split('>')[1].Replace('</a','').Replace('—',' - '), | |
| "KB" + $CurrentPatch.href.Split('/')[-1], | |
| "https://support.microsoft.com" + $CurrentPatch.href, | |
| $LatestAvailablePatch.outerHTML.Split('>')[1].Replace('</a','').Replace('—',' - '), | |
| "KB" + $LatestAvailablePatch.href.Split('/')[-1], | |
| "https://support.microsoft.com" + $LatestAvailablePatch.href | |
| ) | |
| Return $Table |
Thanks for the suggestion! I thought about something like that, but since all the information can be obtained from a single link it meant the code doesn't need to be updated for future releases.
Hi Trevor,
Could be useful to keep only the date on the Update property : Update = ([DateTime]($item.outerHTML.Split('>')[1]).Split('&#x')[0]).ToShortDateString().
It would be great if BIOS version could be added
Hi, I got an error when running the cmdlet:
PS C:\Users\sicopadmin\workspaces\powershell> .\Get-CurrentPatchInfo -ExcludePreview -ExcludeOutofBand
InvalidOperation: C:\Users\sicopadmin\workspaces\powershell\Get-CurrentPatchInfo.ps1:121
Line |
121 | [void]$Table.Rows.Add(
| ~~~~~~~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
PS C:\Users\sicopadmin\workspaces\powershell>
Any advice on how to fix this error from happen again?
Hi, I got an error when running the cmdlet:
PS C:\Users\sicopadmin\workspaces\powershell> .\Get-CurrentPatchInfo -ExcludePreview -ExcludeOutofBand InvalidOperation: C:\Users\sicopadmin\workspaces\powershell\Get-CurrentPatchInfo.ps1:121 Line | 121 | [void]$Table.Rows.Add( | ~~~~~~~~~~~~~~~~~~~~~~ | You cannot call a method on a null-valued expression. PS C:\Users\sicopadmin\workspaces\powershell>
Any advice on how to fix this error from happen again?
That is because its not a windows 10 probably
here is my fix, replace these lines with line number 8 and it will work (only for windows 11 and 10)
$Winver=Get-ComputerInfo | Select OsName
If($winver.'OsName' -like "Microsoft Windows 11*"){$URI = "https://aka.ms/Windows11UpdateHistory" <#Windows 11 release history#> }
Elseif($winver.'OsName' -like "Microsoft Windows 10*"){$URI = "https://aka.ms/WindowsUpdateHistory" <#Windows 10 release history#> }
So if $CurrentPatch is $null/empty, what does this mean?
As per my understanding...
if the Device build version (example 22621.3085) does not match the list of builds in the website "https://aka.ms/WindowsUpdateHistory" (check the left pane) there is no record of the build to match it against a patch, so we get a null value error
one more update
for window 11 device you have to use this URL: "https://aka.ms/WindowsUpdateHistory"
and for windows 10 change it to: https://support.microsoft.com/en-us/topic/windows-10-update-history-8127c2c6-6edf-4fdf-8b9f-0f7be1ef3562
$Winver=Get-ComputerInfo | Select OsName
If($winver.'OsName' -like "Microsoft Windows 11*"){$URI = "https://aka.ms/WindowsUpdateHistory" <#Windows 11 release history#> }
Elseif($winver.'OsName' -like "Microsoft Windows 10*"){$URI = "https://support.microsoft.com/en-us/topic/windows-10-update-history-8127c2c6-6edf-4fdf-8b9f-0f7be1ef3562" <#Windows 10 release history#> }
Thanks for the feedback and comments!
I have updated the code with the following changes:
- Added the correct URLs for update history which are now different between W10/11
- Pull OSEdition from WMI instead of registry (required for Windows 11)
- Dropped ReleaseId for DisplayVersion for OSVersion (ie 23H2 etc)
- Improved the extraction of the OSBuild in the parsed array to allow for proper sorting
- Fixed issue where only 1 update might be returned when using the -ListAvailable switch
Hi, I got an error when running the cmdlet:
PS C:\Users\sicopadmin\workspaces\powershell> .\Get-CurrentPatchInfo -ExcludePreview -ExcludeOutofBand InvalidOperation: C:\Users\sicopadmin\workspaces\powershell\Get-CurrentPatchInfo.ps1:121 Line | 121 | [void]$Table.Rows.Add( | ~~~~~~~~~~~~~~~~~~~~~~ | You cannot call a method on a null-valued expression. PS C:\Users\sicopadmin\workspaces\powershell>
Any advice on how to fix this error from happen again?
same here. @ejespino1127 were you able to fix it?
Nice job Trevor 👍
May I add a suggestion to improve the code.
Instead of getting links from https://aka.ms/WindowsUpdateHistory, you could use the build you grabbed with the
Get-MyWindowsVersionfunction.Using that build, you could use a switch statement to set the URL to parse with Invoke-Webrequest :
20H2: https://support.microsoft.com/en-us/help/4581839
2004: https://support.microsoft.com/en-us/help/4555932
1909: https://support.microsoft.com/en-us/help/4529964
1903: https://support.microsoft.com/en-us/help/4498140
1809: https://support.microsoft.com/en-us/help/4464619
1803: https://support.microsoft.com/en-us/help/4099479
1709: https://support.microsoft.com/en-us/help/4043454
...