#Requires -Version 2.0 param ( [Parameter(Mandatory=$true)] [string]$ID) ## Make sure the hotfix ID is in uppercase for string matching where required. $ID = $ID.ToUpper() ## The next two methods are lightly modified, but mostly lifted from the following pages: # https://social.technet.microsoft.com/wiki/contents/articles/4197.windows-how-to-list-all-of-the-windows-and-software-updates-applied-to-a-computer.aspx # https://superuser.com/questions/1002015/why-are-get-hotfix-and-wmic-qfe-list-in-powershell-missing-installed-updates ## Check WMI using Microsoft's "QuickFixEngineering" to see if it has a record ## This method will return updates for the Windows OS and components only ### This method requires Windows Vista / Windows Server 2008 or higher If ( ([System.Environment]::OSVersion.Version).Major -ge 6 ) { #If ( Get-WmiObject -Class "win32_quickfixengineering" | Where { $_.HotfixID -like "*${ID}*" } ) #{ $BeanCounter +=1 } } ## Next we'll search Windows Update using the Windows API. ## This will return a lot more results than the other methods, ## but will not return manually installed hotfixes/updates. ### This method is the most compatible for finding updates, but the uninstall process won't work in Windows 10 :( If ( ([System.Environment]::OSVersion.Version).Major -lt 10 ) { $UpdateSession = New-Object -ComObject Microsoft.Update.Session $Searcher = $UpdateSession.CreateUpdateSearcher() $HistoryCount = $Searcher.GetTotalHistoryCount() If ( $Searcher.QueryHistory(0, $HistoryCount) | Select-Object Title, @{name="Operation"; expression={ switch($_.operation) { 1 {"Installation" }; } } } | Where { $_.Title -like "*${ID}*" } ) { ## This will remove the "KB" prefix that may have been added (case-insensitive) ## When we invoke wusa.exe we need to specify the KB number without "KB" in front. $UninstallID = $ID -ireplace 'kb', '' ## Uninstall the hotfix ## Note: This exact method to uninstall a hotfix doesn't work in Windows 10 ## If you omit the /quiet switch, it will *say* it uninstalled the update, but it never gets uninstalled. Start-Process "wusa.exe" -ArgumentList "/uninstall /kb:${UninstallID} /quiet /norestart" -Wait } } ## Lastly, we'll query DISM for any packages it has installed to see if our hotfix is there ### This method is really only for Windows 10 endpoints, but we'll target Vista and up just to cover the bases. If ( ([System.Environment]::OSVersion.Version).Major -ge 6 ) { $DISMPackages = ( DISM.exe /Online /Get-Packages | findstr "${ID}" ) $DISMPackages = If ( $DISMPackages ) { $DISMPackages.Replace('Package Identity : ','').Trim() } Foreach ( $package in $DISMPackages ) { Start-Process "DISM.exe" -ArgumentList "/Online /Remove-Package /PackageName:${package} /quiet /norestart" -Wait } } ## TODO: ## Search for all manually installed hotfixes/updates ## I guess a good place to start is MSI, MSU, and CAB packages installed by a user. ## (possibly by searching for MSI property strings of installed packages...??) ## If it isn't installed, just print out a message stating as much. Else { Write-Host "The hotfix '${ID}' was not found." }