After battling this exact issue across multiple environments, I've compiled a comprehensive diagnostic approach. The core symptom: WSUS reports updates as "Not Applicable" for Server 2016 while identical configurations work for Server 2012. Let's break down the technical investigation.
First, validate these registry settings on affected 2016 servers:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate]
"WUServer"="http://your-wsus-server:8530"
"WUStatusServer"="http://your-wsus-server:8530"
"TargetGroupEnabled"=dword:00000001
"TargetGroup"="Your_WSUS_Group"
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]
"UseWUServer"=dword:00000001
"DetectionFrequencyEnabled"=dword:00000001
"DetectionFrequency"=dword:00000004
Run this comprehensive check on problematic nodes:
# WSUS Client Diagnostic Tool
$ErrorActionPreference = "Stop"
# Check basic WSUS connectivity
Test-NetConnection -ComputerName your-wsus-server -Port 8530
# Verify Windows Update services
Get-Service -Name wuauserv, bits | Select-Object Name, Status
# Check update history (should be empty for fresh installs)
Get-WindowsUpdateLog | Select-String -Pattern "2016" -Context 3
# Force update detection
Start-Process "wuauclt.exe" -ArgumentList "/detectnow" -Wait
Start-Process "wuauclt.exe" -ArgumentList "/reportnow" -Wait
# Check registry settings
$regPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
Get-ItemProperty -Path $regPath | Format-List
The most common root cause I've found is incorrect product categorization in WSUS:
- Open WSUS Console → Options → Products and Classifications
- Ensure "Windows Server 2016" is checked under Products
- Verify "Critical Updates" and "Security Updates" are selected under Classifications
- For fresh installs, add "Upgrades" classification temporarily
When updates appear as "Not Applicable" incorrectly:
# Stop services
Stop-Service -Name wuauserv, bits -Force
# Clear cache
Remove-Item -Path "$env:windir\SoftwareDistribution\*" -Recurse -Force
# Reset Windows Update components
Start-Process -FilePath "dism.exe" -ArgumentList "/online /cleanup-image /restorehealth" -Wait
Start-Process -FilePath "sfc.exe" -ArgumentList "/scannow" -Wait
# Re-register DLLs
$dlls = @(
"atl.dll","wuapi.dll","wuaueng.dll","wuaueng1.dll","wucltui.dll",
"wups.dll","wups2.dll","wuwebv.dll"
)
foreach ($dll in $dlls) {
regsvr32.exe /s $dll
}
# Restart services
Start-Service -Name bits
Start-Service -Name wuauserv
On your WSUS server, verify these IIS settings:
# Check IIS compression settings
Get-WebConfigurationProperty -Filter /system.webServer/httpCompression -Name *
# Should show these MIME types are enabled:
# application/octet-stream
# application/x-msdownload
After implementing all fixes, run this verification sequence:
# Check update readiness
Get-WindowsUpdate -MicrosoftUpdate -NotCategory "Drivers" |
Where-Object {$_.Title -like "*2016*"} |
Format-Table Title, IsDownloaded, IsInstalled
# Alternative method using COM object
$Session = New-Object -ComObject Microsoft.Update.Session
$Searcher = $Session.CreateUpdateSearcher()
$SearchResult = $Searcher.Search("IsInstalled=0 and Type='Software'")
$SearchResult.Updates | Where-Object {$_.Title -match "2016"} |
Select-Object Title, IsDownloaded, IsInstalled
Remember that WSUS synchronization can take up to 24 hours after configuration changes. For immediate results, manually synchronize from the WSUS console.
When dealing with WSUS and Windows Server 2016, we're observing a peculiar behavior where updates appear as "Installed or Not Applicable" despite being fresh installations. The Windows Update client seems to misreport update status, creating a dangerous false-negative scenario for system administrators.
# Verify WSUS client configuration
Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "WUServer"
# Check update history (should be empty for fresh installs)
Get-WindowsUpdateLog -EtwLevel Verbose -EtwKeywords All
After confirming basic connectivity, we need to examine the update classification behavior. This PowerShell snippet helps validate the client-side WSUS configuration:
# Check update classifications being synced
$wsus = Get-WsusServer
$wsus.GetUpdateClassifications() | Select-Object -Property Title, Id
Windows Server 2016 introduced a new product category structure in WSUS. Many administrators miss that it requires explicit selection in WSUS console under:
Options → Products and Classifications → Products
Ensure "Windows Server 2016" is checked, not just "Windows Server". The product ID changed significantly from previous versions.
The Windows Update client database frequently gets corrupted. This sequence completely resets it:
net stop wuauserv
net stop cryptSvc
net stop bits
net stop msiserver
Remove-Item "C:\Windows\SoftwareDistribution\*" -Recurse -Force
net start wuauserv
net start cryptSvc
net start bits
net start msiserver
wuauclt /resetauthorization /detectnow
On the WSUS server, enable verbose logging through IIS:
# Enable WSUS API logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Update Services\Server\Setup" -Name "EnableApiLogging" -Value 1
Then examine the IIS logs for client requests (typically in C:\inetpub\logs\LogFiles\W3SVC1
). Look for 200 responses to /ClientWebService/client.asmx
calls.
When standard detection methods fail, this PowerShell script forces complete synchronization:
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
$SearchResult = $UpdateSearcher.Search("IsInstalled=0")
$SearchResult.Updates | Select-Object Title,MsrcSeverity
Windows Server 2016 enforces stricter SSL requirements. Verify your WSUS SSL certificate chain with:
Test-NetConnection -ComputerName WSUS_SERVER -Port 8531
Get-ChildItem -Path Cert:\LocalMachine\TrustedPublisher
Run these SQL commands against the SUSDB to clean up potential metadata issues:
USE SUSDB
GO
EXEC spGetConfigValue 'SchemaVersion'
GO
EXEC spCleanupObsoleteUpdates
GO
After implementing all fixes, this comprehensive check validates proper update detection:
# Check update service connectivity
Test-WSUSClient -WsusServerName "WSUS_SERVER" -Port 8531 -UseSsl
# Verify update categories
(New-Object -ComObject Microsoft.Update.ServiceManager).Services |
Where-Object { $_.IsDefaultAUService -eq $true } |
Select-Object Name, ServiceID