How to Check if a Specific Windows Update (KB) is Installed in Batch Script
Windows Updates are identified by their Knowledge Base (KB) number, such as KB5034441 or KB4056892. Before deploying software, running compliance audits, or troubleshooting issues caused by a specific patch, administrators need to verify whether a particular KB article has been installed on a machine. A Batch Script can automate this check across single machines or entire fleets, reporting installation status and providing detailed patch information.
In this guide, we will explore how to check for specific Windows Updates by their KB number from a Batch Script using wmic, systeminfo, PowerShell, and the Windows Update COM object.
Method 1: Using WMIC
The wmic qfe command queries the Quick Fix Engineering list, which contains all installed hotfixes and updates:
@echo off
setlocal
set "KB=%~1"
if not defined KB (
set /p "KB=Enter KB number (e.g., KB5034441): "
)
:: Normalize input (add KB prefix if missing)
echo %KB% | findstr /i "^KB" >nul || set "KB=KB%KB%"
echo Checking for %KB%...
wmic qfe where "HotFixID='%KB%'" get HotFixID /value 2>nul | findstr /i "%KB%" >nul
if %errorlevel% equ 0 (
echo [FOUND] %KB% is installed.
echo.
echo Details:
wmic qfe where "HotFixID='%KB%'" get HotFixID,Description,InstalledOn /format:list 2>nul
) else (
echo [NOT FOUND] %KB% is NOT installed on this machine.
)
pause
Example usage:
check_kb.bat KB5034441
Example output:
Checking for KB5034441...
[FOUND] KB5034441 is installed.
Details:
Description=Update
HotFixID=KB5034441
InstalledOn=1/9/2024
Method 2: Using systeminfo and findstr
The systeminfo command includes a "Hotfix(s)" section:
@echo off
setlocal
set "KB=%~1"
if not defined KB set /p "KB=Enter KB number: "
echo %KB% | findstr /i "^KB" >nul || set "KB=KB%KB%"
echo Checking for %KB% (this may take a moment)...
systeminfo 2>nul | findstr /i "%KB%" >nul
if %errorlevel% equ 0 (
echo [FOUND] %KB% is installed.
) else (
echo [NOT FOUND] %KB% is NOT installed.
)
pause
systeminfo can take 10–30 seconds to run because it gathers comprehensive system data. For faster checks, prefer wmic qfe (Method 1) which queries only the hotfix list.
Method 3: Check Multiple KBs at Once
Verify a list of required patches:
@echo off
setlocal enabledelayedexpansion
echo =============================================
echo WINDOWS UPDATE COMPLIANCE CHECK
echo %COMPUTERNAME% - %date%
echo =============================================
echo.
:: Define required updates
set "updates=KB5034441 KB5033372 KB4056892 KB5031356"
:: Cache the installed hotfix list once
set "cache=%temp%\hotfix_list_%random%.txt"
wmic qfe get HotFixID /format:csv > "%cache%" 2>nul
set "installed=0"
set "missing=0"
for %%K in (%updates%) do (
findstr /i "%%K" "%cache%" >nul 2>&1
if !errorlevel! equ 0 (
echo [OK] %%K
set /a "installed+=1"
) else (
echo [MISSING] %%K
set /a "missing+=1"
)
)
del "%cache%" >nul 2>&1
echo.
echo Results: !installed! installed, !missing! missing
echo.
if !missing! gtr 0 (
echo [WARNING] This system is missing !missing! required update(s^).
) else (
echo [OK] All required updates are installed.
)
pause
Method 4: Detailed Patch Report
Generate a full report of a specific KB with all available metadata:
@echo off
setlocal enabledelayedexpansion
set "KB=%~1"
if not defined KB set /p "KB=Enter KB number: "
echo %KB% | findstr /i "^KB" >nul || set "KB=KB%KB%"
echo =============================================
echo PATCH DETAIL REPORT: %KB%
echo =============================================
echo.
:: Check installation status
wmic qfe where "HotFixID='%KB%'" get HotFixID /value 2>nul | findstr /i "%KB%" >nul
if %errorlevel% neq 0 (
echo Status: NOT INSTALLED
echo.
echo This update has not been applied to %COMPUTERNAME%.
pause
exit /b 1
)
echo Status: INSTALLED
echo.
:: Get full details
for /f "tokens=1,* delims==" %%A in (
'wmic qfe where "HotFixID='%KB%'" get /format:list 2^>nul ^| findstr "="'
) do (
set "val=%%B"
echo %%A: !val!
)
echo.
echo Machine: %COMPUTERNAME%
echo Checked: %date% %time:~0,8%
pause
Method 5: PowerShell-Enhanced Check with History
Use PowerShell from Batch for richer update information:
@echo off
setlocal
set "KB=%~1"
if not defined KB set /p "KB=Enter KB number: "
echo %KB% | findstr /i "^KB" >nul || set "KB=KB%KB%"
echo Checking %KB% via multiple sources...
echo.
:: Method A: QFE check
echo [1] Quick Fix Engineering (wmic qfe):
wmic qfe where "HotFixID='%KB%'" get HotFixID,InstalledOn /value 2>nul | findstr /i "%KB%"
if %errorlevel% neq 0 echo Not found in QFE list.
echo.
:: Method B: Windows Update history (catches updates not in QFE)
echo [2] Windows Update History:
powershell -NoProfile -Command ^
"try { " ^
" $session = New-Object -ComObject 'Microsoft.Update.Session'; " ^
" $searcher = $session.CreateUpdateSearcher(); " ^
" $count = $searcher.GetTotalHistoryCount(); " ^
" if ($count -gt 0) { " ^
" $history = $searcher.QueryHistory(0, $count); " ^
" $match = @($history | Where-Object { $_.Title -match '%KB%' }); " ^
" if ($match.Count -gt 0) { " ^
" foreach ($entry in $match) { " ^
" $resultText = switch ([int]$entry.ResultCode) { " ^
" 1 {'In Progress'} 2 {'Succeeded'} 3 {'Succeeded with Errors'} " ^
" 4 {'Failed'} 5 {'Aborted'} default {'Unknown'} " ^
" }; " ^
" Write-Host (' Title: ' + $entry.Title); " ^
" Write-Host (' Date: ' + $entry.Date.ToString('yyyy-MM-dd HH:mm')); " ^
" Write-Host (' Result: ' + $resultText); " ^
" Write-Host ''; " ^
" } " ^
" } else { " ^
" Write-Host ' Not found in update history.'; " ^
" } " ^
" } else { " ^
" Write-Host ' Update history is empty.'; " ^
" } " ^
"} catch { " ^
" Write-Host (' [ERROR] ' + $_.Exception.Message); " ^
"}"
pause
The wmic qfe list only includes hotfixes and security updates. Some cumulative or feature updates appear only in the Windows Update history. Method 5 checks both sources for comprehensive coverage.
Method 6: Remote Machine Check
Check if a KB is installed on a remote computer:
@echo off
setlocal
set "KB=%~1"
set "REMOTE=%~2"
if not defined KB set /p "KB=KB number: "
if not defined REMOTE set /p "REMOTE=Remote computer name: "
echo %KB% | findstr /i "^KB" >nul || set "KB=KB%KB%"
echo Checking %KB% on %REMOTE%...
wmic /node:"%REMOTE%" qfe where "HotFixID='%KB%'" get HotFixID /value 2>nul | findstr /i "%KB%" >nul
if %errorlevel% equ 0 (
echo [FOUND] %KB% is installed on %REMOTE%.
echo.
wmic /node:"%REMOTE%" qfe where "HotFixID='%KB%'" get HotFixID,InstalledOn /format:list 2>nul
) else (
echo [NOT FOUND] %KB% is NOT installed on %REMOTE%.
)
pause
Listing All Installed Updates
@echo off
echo All installed hotfixes on %COMPUTERNAME%:
echo.
wmic qfe get HotFixID,Description,InstalledOn /format:table 2>nul
pause
Common Mistakes
The Wrong Way: Searching Without the KB Prefix
:: WRONG - Searching for just the number may match unrelated text
systeminfo | findstr "5034441"
:: Could match dates, memory values, or other numbers
Output Concern:
The number alone might appear in unrelated fields of the systeminfo output. Always include the KB prefix (findstr "KB5034441") or use wmic qfe which searches only the hotfix ID field.
The Wrong Way: Using a Broad findstr Against the Full QFE List
:: WRONG - Searching the entire wmic output for a substring
wmic qfe get HotFixID | findstr /i "KB503"
:: Matches KB5034441, KB5033372, KB5031356, and any other KB starting with 503
Always use the where "HotFixID='KBxxxxxxx'" filter in wmic to match the exact KB number, or use the full KB string with findstr to avoid partial matches.
The Wrong Way: Using Only systeminfo
:: SLOW - Gathers all system data just to check one value
systeminfo | findstr /i "KB5034441"
:: Takes 10-30 seconds for a simple yes/no check
systeminfo collects processor, memory, network, and boot data before listing hotfixes. Use wmic qfe for faster, targeted queries.
Best Practices
- Normalize KB input: Accept input with or without the
KBprefix and standardize it. - Use
wmic qfefor speed: It queries only the hotfix database, unlikesysteminfo. - Check multiple sources: Some updates appear in Windows Update history but not in
wmic qfe. - Cache the hotfix list: When checking multiple KBs, query
wmic qfeonce and search the cached result. - Include machine context: Log the computer name and date with results for audit trails.
Conclusion
Checking if a specific Windows Update is installed from a Batch Script is most efficiently done with wmic qfe filtered by the KB number. For comprehensive coverage, combining wmic qfe with the Windows Update COM object history ensures no update is missed. By normalizing KB input, caching hotfix lists for batch checks, and supporting remote machine queries, administrators build compliance verification tools that confirm patch status across individual machines or entire environments.