#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." }

