Skip to main content

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
info

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
tip

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

  1. Normalize KB input: Accept input with or without the KB prefix and standardize it.
  2. Use wmic qfe for speed: It queries only the hotfix database, unlike systeminfo.
  3. Check multiple sources: Some updates appear in Windows Update history but not in wmic qfe.
  4. Cache the hotfix list: When checking multiple KBs, query wmic qfe once and search the cached result.
  5. 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.