68 lines
3.2 KiB
PowerShell
68 lines
3.2 KiB
PowerShell
#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." }
|
|
|