You want every Windows box on the network to pull patches from one server you control, without paying for Intune or Configuration Manager. That is still what WSUS does, and you can still install WSUS on Windows Server 2025 even though Microsoft has stopped developing it. We built a small homelab to check how much of the old routine survives: one Windows Server 2025 VM running the WSUS role, plus a Windows 11 workstation that gets its WSUS settings from a domain Group Policy Object.
This guide covers the role install (WID or SQL Server), the WSUS configuration wizard and its PowerShell equivalents, products and classifications, the WSUS Group Policy client settings with client-side targeting, approvals and cleanup. It also gives the current deprecation status from Microsoft Learn, so you know what you are signing up for. I ran through this on Windows Server 2025 build 26100 with a Windows 11 24H2 client in October 2026, and it works end to end.
Is WSUS Deprecated in Windows Server 2025?
Yes, but deprecated does not mean removed. Microsoft lists Windows Server Update Services under “Features no longer in development” for Windows Server 2025. Its entry is short. “WSUS is no longer actively developed. All the existing capabilities and content continue to be available for your deployments.” The same page defines the term. A deprecated component “still ships in Windows Server, is supported for production deployments, and continues to receive security and quality updates per the product lifecycle.” You can read it on the Features removed or no longer developed in Windows Server page.
Three more facts from that page and our lab matter for anyone planning a WSUS server today. WID is the default WSUS database, and the old wuauclt.exe /detectnow trick no longer works, so client checks in this guide use the Windows Update COM API instead.
- WID is deprecated and “will be removed from Windows in a future release”
wuauclt.exe /detectnowis listed as removed since Server 2016- The role still installs, as version 10.0.26100.32230 here
Our take is simple. If your machines are on-premises, domain-joined and you want a free approval gate in front of Patch Tuesday, WSUS on Server 2025 is still a reasonable choice, because it is supported for the life of the OS. If you are building something that has to last ten years, or most of your fleet is laptops that rarely see the office network, plan for a cloud-managed option and treat WSUS as the bridge. If WSUS is your first Windows Server role beyond AD, our pick of Windows Server administration books fills in the background this guide skips. Because WID is on the way out too, a new deployment that expects to grow should think about SQL Server for the database from day one.
How the Lab Fits Together
Only the WSUS server talks to Microsoft Update. Every client talks to WSUS over HTTP on port 8530, and it learns the server URL and its computer group from a GPO, which is the whole point of the design. In our homelab the same VM also runs the domain controller for homelab.lan, purely to keep the lab to two machines:

In production, keep WSUS on a member server and leave the domain controllers alone. Everything below works the same way on a member server, and the only DC-specific part is where you create the GPO.
Prerequisites
Microsoft’s WSUS planning guide recommends 40 GB or more of free disk and an extra 2 GB of RAM for the role. Our lab used these, and you should treat them as a floor rather than a target:
- Windows Server 2025 Desktop Experience, 4 vCPU, 8 GB RAM
- A 40 GB data disk for content, mounted as
D: - An Active Directory domain for the Group Policy part
- Outbound TCP 80 and 443 to Microsoft Update
- Inbound TCP 8530 (HTTP) or 8531 (HTTPS) from clients
- One domain-joined Windows 11 24H2 test client
If you still need the base OS or the domain, start with our Windows Server 2025 install guide and the AD DS setup on Windows Server, then come back here. Size the content disk by what you approve, not by what you sync. Metadata lives in the database, while the update files land on disk only for approved updates (unless you tell WSUS to download everything), so a narrow product list keeps both small. The planning guide adds about 10 GB of content per Windows version and architecture once local UUP content is involved, so a mixed Windows 10, Windows 11 and Server fleet outgrows 40 GB quickly.
Step 1: Install the WSUS Role (WID or SQL Server)
The first decision is the database. WID needs nothing extra, while SQL Server (Express, Standard or Enterprise) is the alternative, and a full SQL Server installation is required if you ever want load-balanced WSUS servers. You pick it through role services: WID Connectivity for the built-in database, or SQL Server Connectivity for an external instance, never both. If you go the SQL route, have the instance ready first, for example with our SQL Server on Windows Server guide.
In Server Manager, the path is Manage > Add Roles and Features > Windows Server Update Services, then accept the IIS and .NET features it pulls in. On the Role Services page leave WID Connectivity and WSUS Services ticked. We used PowerShell instead, from an elevated window, which installs the WID variant plus the console:
Install-WindowsFeature -Name UpdateServices -IncludeManagementTools
On our VM the install took 188 seconds and ended with a warning that is safe to ignore, because the next step is exactly the “additional configuration” it is asking for:
WARNING: Additional configuration may be required. Review the article Managing WSUS Using PowerShell at TechNet Library (http://go.microsoft.com/fwlink/?LinkId=235499) for more information on the recommended steps to perform WSUS installation using PowerShell.
Confirm which role services landed.
Get-WindowsFeature -Name UpdateServices*
WID Connectivity and WSUS Services should be installed, with SQL Server Connectivity still only available:
Display Name Name Install State
------------ ---- -------------
[X] Windows Server Update Services UpdateServices Installed
[X] WID Connectivity UpdateServices-WidDB Installed
[X] WSUS Services UpdateServices-Services Installed
[ ] SQL Server Connectivity UpdateServices-DB Available
[X] Windows Server Update Services Tools UpdateServices-RSAT Installed
[X] API and PowerShell cmdlets UpdateServices-API Installed
[X] User Interface Management Console UpdateServices-UI Installed
For SQL Server, install the UpdateServices-Services and UpdateServices-DB role services instead of the default set, then give the post-install step in Step 2 the instance name. We only tested WID in this lab, so treat these two lines as the documented shape rather than something we ran, with SQL01\WSUS standing in for your server and instance:
Install-WindowsFeature -Name UpdateServices-Services,UpdateServices-DB -IncludeManagementTools
& "C:\Program Files\Update Services\Tools\wsusutil.exe" postinstall SQL_INSTANCE_NAME="SQL01\WSUS" CONTENT_DIR=D:\WSUS
Either way, check the Restart Needed column of the install output before you continue, and finish any pending restart before running the post-install task.
Step 2: Run the WSUS Post-Install Task
The role is not usable until the post-install task creates the database, the content folder and the IIS site. If you installed from Server Manager, its wizard asked for the folder on the Content location selection page, and the Launch Post-Installation tasks link in the notification flag uses that path. From PowerShell you run wsusutil.exe yourself, which is also the version you can script. Point it at the data disk so update files do not fill C::
New-Item -Path D:\WSUS -ItemType Directory -Force
& "C:\Program Files\Update Services\Tools\wsusutil.exe" postinstall CONTENT_DIR=D:\WSUS
It ran for 115 seconds here. The console only prints a short status, so the useful record is the WSUS_PostInstall_<timestamp>.log it writes to the temp folder of the account that ran it (ours ran as SYSTEM, so it landed in C:\Windows\SystemTemp). The relevant lines of ours show something the wizard never tells you: post-install already enables three classifications and creates the default approval rule before you touch anything:
2026-10-30 04:10:13 Creating default subscription.
2026-10-30 04:10:15 Adding Critical Updates classification
2026-10-30 04:10:15 Adding Security Updates classification
2026-10-30 04:10:15 Adding Definition Updates classification
...
2026-10-30 04:10:15 Creating default subscription succeeded.
2026-10-30 04:10:15 Populating Auto-Approval Rules.
2026-10-30 04:10:15 Populating Auto-Approval Rules Succeeded.
2026-10-30 04:10:15 StartServer completed successfully.
...
2026-10-30 04:10:15 Postinstall completed
The install also opens the firewall for you. Check the IIS bindings and the rules it created.
Get-WebBinding -Name 'WSUS Administration' | Format-Table protocol, bindingInformation
Get-NetFirewallRule -DisplayName WSUS | Get-NetFirewallPortFilter | Format-Table Protocol, LocalPort
Both ports show up, HTTP on 8530 and HTTPS on 8531, with two inbound “WSUS” allow rules to match:
protocol bindingInformation
-------- ------------------
http :8530:
https :8531:
Protocol LocalPort
-------- ---------
TCP 8531
TCP 8530
Our server reported UseSecureConnection : False (Step 3 shows where), so clients talk plain HTTP on 8530. Moving them to 8531 needs a certificate on the WSUS site plus wsusutil configuressl, which this lab did not cover. Plan for it in production, because on plain HTTP the update metadata crosses the network unencrypted. If your server sits behind another firewall, our guide to opening a port in Windows Server firewall covers the PowerShell and GUI ways to do it.
Step 3: Run the WSUS Configuration Wizard
Open the console from Server Manager > Tools > Windows Server Update Services. On our server it opened straight to the dashboard rather than the wizard, so we launched the WSUS configuration wizard from Options. That page also holds every setting the wizard touches, each on its own:

- 1Products and Classifications
- 2Synchronization Schedule
- 3Computers
- 4Server Cleanup Wizard
- 5WSUS Server Configuration Wizard
- Products and Classifications sets what WSUS syncs
- Synchronization Schedule sets when it syncs
- Computers picks console or Group Policy groups
- Server Cleanup Wizard does monthly housekeeping
- WSUS Server Configuration Wizard reopens the wizard
The wizard walks through Before You Begin, the Microsoft Update Improvement Program, Choose Upstream Server, Specify Proxy Server, Connect to Upstream Server, Choose Languages, Choose Products, Choose Classifications and Configure Sync Schedule. For a standalone server there is only one real decision on the upstream page, and it is already the default:

- 1Choose Upstream Server
- 2Synchronize from Microsoft Update
- 3server is synchronizing
- 4Next
- Choose Upstream Server is the current page
- Synchronize from Microsoft Update stays selected on a standalone server
- The server is synchronizing bar blocks saving until the sync ends
- Next moves on to the proxy page
We got that yellow bar because we had already started the first sync from PowerShell, which is the same job as the wizard’s Connect to Upstream Server page. That page downloads the list of products, classifications and languages, and until it finishes you cannot pick products, so the wizard holds you there:

- 1Start Connecting
- 2Stop Connecting
- Start Connecting starts the category download
- Stop Connecting cancels it
Start Connecting was greyed out in our capture because the PowerShell sync was already running, and you should not press Stop Connecting on a first run. If you prefer scripts, these lines do what the first wizard pages do: sync from Microsoft Update, keep English only, and start the category-only sync. Limiting languages early matters, because every extra language adds metadata and files WSUS has to keep:
Set-WsusServerSynchronization -SyncFromMU
$wsus = Get-WsusServer
$config = $wsus.GetConfiguration()
$config.AllUpdateLanguagesEnabled = $false
$config.SetEnabledUpdateLanguages('en')
$config.Save()
$sub = $wsus.GetSubscription()
$sub.StartSynchronizationForCategoryOnly()
It is also worth one look at what the console connects to, because the port and the SSL flag decide the URL your clients will need later:
Get-WsusServer | Format-List Name, Version, PortNumber, UseSecureConnection
Ours is the 2025 build of the role on plain HTTP port 8530:
Name : WSUS01
Version : 10.0.26100.32230
PortNumber : 8530
UseSecureConnection : False
When you run the configuration block, the first cmdlet confirms the upstream choice in plain words.
The Update Server was successfully configured with the following parameters:
Synchronize from Microsoft Update
Watch the category sync with $sub.GetSynchronizationStatus() and $sub.GetSynchronizationProgress(). Ours started at 04:37 and finished at 05:02, so about 26 minutes on a 4 vCPU VM, and the progress counter sat at “Categories 0/4255” for nearly all of it. Do not cancel it because the number does not move. The last sync info is the reliable signal:
$sub.GetLastSynchronizationInfo() | Format-List StartTime, EndTime, Result, Error
A finished category sync reads Succeeded with no error, and only then do the product and classification lists fill in:
StartTime : 10/30/2026 4:37:13 AM
EndTime : 10/30/2026 5:02:58 AM
Result : Succeeded
Error : NotApplicable
Pick a sync time too. In the wizard that is the Configure Sync Schedule page; in PowerShell it is three properties on the same subscription object, set in the next step together with the products.
Step 4: Pick Products and Classifications
The product list is where most WSUS servers go wrong, because every ticked box adds metadata to sync and updates to judge. Tick only what you run. The names are not always obvious either. Windows Server 2025 does not appear under that name; it is Microsoft Server Operating System-24H2. After the category sync, this is what our server offered for the two systems in the lab:
Get-WsusProduct | Where-Object { $_.Product.Title -match 'Windows 11|Server Operating System|Windows Server 2025' } | ForEach-Object { $_.Product.Title } | Sort-Object
Most of the Windows 11 entries are driver categories per feature update. The two you want for patching are the plain Windows 11 and the 24H2 server entry.
Azure File Sync agent updates for Windows Server 2025
Microsoft Server operating system-21H2
Microsoft Server Operating System-22H2
Microsoft Server Operating System-23H2
Microsoft Server Operating System-24H2
Windows 11
Windows 11 Client S, version 22H2 and later, Servicing Drivers
Windows 11 Client S, version 22H2 and later, Upgrade & Servicing Drivers
Windows 11 Client S, version 24H2 and later, Servicing Drivers
Windows 11 Client S, version 24H2 and later, Upgrade & Servicing Drivers
Windows 11 Client S, version 24H2 and later, Upgrade & Servicing Drivers
Windows 11 Client S, version 25H2 and later, Servicing Drivers
Windows 11 Client S, version 25H2 and later, Upgrade & Servicing Drivers
Windows 11 Client S, version 26H1 and later, Servicing Drivers
Windows 11 Client S, version 26H1 and later, Upgrade & Servicing Drivers
Windows 11 Client, version 22H2 and later, Servicing Drivers
Windows 11 Client, version 22H2 and later, Upgrade & Servicing Drivers
Windows 11 Client, version 24H2 and later, Servicing Drivers
Windows 11 Client, version 24H2 and later, Upgrade & Servicing Drivers
Windows 11 Client, version 25H2 and later, Servicing Drivers
Windows 11 Client, version 25H2 and later, Upgrade & Servicing Drivers
Windows 11 Client, version 26H1 and later, Servicing Drivers
Windows 11 Client, version 26H1 and later, Upgrade & Servicing Drivers
Windows 11 Dynamic Update
Windows 11 GDR-DU
For classifications we kept the three that post-install had already turned on and added Update Rollups. Drivers, Feature Packs, Upgrades and Tools stay off, because none of them are needed to keep machines patched and each one adds metadata to sync. This script disables everything else, enables our choices and sets one sync a day at 02:00, which is what the Choose Products, Choose Classifications and Configure Sync Schedule pages of the wizard do:
$Products = 'Windows 11','Microsoft Server Operating System-24H2'
$wsus = Get-WsusServer
Get-WsusProduct | Where-Object { $_.Product.Title -notin $Products } | Set-WsusProduct -Disable
Get-WsusProduct | Where-Object { $_.Product.Title -in $Products } | Set-WsusProduct
$classes = 'Critical Updates','Security Updates','Definition Updates','Update Rollups'
Get-WsusClassification | Where-Object { $_.Classification.Title -notin $classes } | Set-WsusClassification -Disable
Get-WsusClassification | Where-Object { $_.Classification.Title -in $classes } | Set-WsusClassification
"Enabled products:"
$wsus.GetSubscription().GetUpdateCategories() | ForEach-Object { " " + $_.Title }
"Enabled classifications:"
$wsus.GetSubscription().GetUpdateClassifications() | ForEach-Object { " " + $_.Title }
$sub = $wsus.GetSubscription()
$sub.SynchronizeAutomatically = $true
$sub.SynchronizeAutomaticallyTimeOfDay = (New-TimeSpan -Hours 2)
$sub.NumberOfSynchronizationsPerDay = 1
$sub.Save()
$wsus.GetInstallApprovalRules() | Format-Table Name, Enabled -AutoSize
Read the lists back before syncing. If anything extra shows up, the filter did not match its exact title. The last table is the approval rule post-install created, and it is switched off:
Enabled products:
Microsoft Server Operating System-24H2
Windows 11
Enabled classifications:
Critical Updates
Definition Updates
Security Updates
Update Rollups
Name Enabled
---- -------
Default Automatic Approval Rule False
Then run the first full sync with $sub.StartSynchronization(), or Synchronizations > Synchronize Now in the console. Ours took 945 seconds for two products and four classifications, finished with Result : Succeeded, and left 504 updates in the catalog. The content disk held just 0.08 GB afterwards, because a sync only brings metadata; the update files arrive with approvals in Step 8.
Step 5: Create Computer Groups for Targeting
Computer groups are how you stage patches. You approve for a pilot group first, then for everyone else a week later. WSUS can fill the groups in two ways:
- Server-side targeting: you drag computers into groups
- Client-side targeting: Group Policy names the group
Dragging computers around is fine for ten machines and painful for two hundred. With client-side targeting the OU a computer sits in decides its patch ring, so we use it here.
Create the groups and switch the targeting mode.
$wsus = Get-WsusServer
$wsus.CreateComputerTargetGroup('Pilot') | Out-Null
$wsus.CreateComputerTargetGroup('Production') | Out-Null
$config = $wsus.GetConfiguration()
$config.TargetingMode = 'Client'
$config.Save()
$wsus.GetComputerTargetGroups() | Format-Table Name, Id
Two groups always exist, All Computers and Unassigned Computers, and our two new ones sit beside them:
Name Id
---- --
All Computers a0a08746-4dbe-4a37-9adf-9e7652c0b421
Pilot af2b9c91-f489-459e-9fd9-2baf6e7301d9
Production 1fe3982c-beea-4b0f-8017-c49b1ef6efb1
Unassigned Computers b73ca6ed-5727-47f3-84de-015e03f6a88a
The group name must match what the GPO sends, character for character. If the name the client sends does not match a group on the server, the approvals you make for Pilot never reach it. In the console, the same switch is Options > Computers > Use Group Policy or registry settings on computers.
Step 6: Point Clients at WSUS with Group Policy
The WSUS Group Policy client settings live in a GPO linked to the OU that holds your pilot machines. In the Administrative Templates that ship with Windows Server 2025, they sit in subfolders of Computer Configuration > Policies > Administrative Templates > Windows Components > Windows Update. Older guides list them flat under Windows Update, which sends you looking in the wrong place. The GPO report from our lab shows exactly where each one sits:
| Policy | Folder under Windows Update | Value we set |
|---|---|---|
| Specify intranet Microsoft update service location | Manage updates offered from Windows Server Update Service | http://wsus01.homelab.lan:8530 for both URLs |
| Enable client-side targeting | Manage updates offered from Windows Server Update Service | Pilot |
| Configure Automatic Updates | Manage end user experience | 4, every day at 03:00 |
You can click through those three policies in gpmc.msc, or set the same registry values with the GroupPolicy module, which is what we did so the result is repeatable. Run this on a domain controller or any machine with the GPMC and AD PowerShell tools. It creates the Pilot Workstations OU first, so change the domain path, the server URL and the OU name to yours:
New-ADOrganizationalUnit -Name 'Pilot Workstations' -Path 'DC=homelab,DC=lan'
$gpo = New-GPO -Name 'WSUS - Pilot Workstations'
$wu = 'HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate'
$au = "$wu\AU"
$url = 'http://wsus01.homelab.lan:8530'
Set-GPRegistryValue -Name $gpo.DisplayName -Key $wu -ValueName WUServer -Type String -Value $url
Set-GPRegistryValue -Name $gpo.DisplayName -Key $wu -ValueName WUStatusServer -Type String -Value $url
Set-GPRegistryValue -Name $gpo.DisplayName -Key $wu -ValueName TargetGroupEnabled -Type DWord -Value 1
Set-GPRegistryValue -Name $gpo.DisplayName -Key $wu -ValueName TargetGroup -Type String -Value 'Pilot'
Set-GPRegistryValue -Name $gpo.DisplayName -Key $au -ValueName UseWUServer -Type DWord -Value 1
Set-GPRegistryValue -Name $gpo.DisplayName -Key $au -ValueName NoAutoUpdate -Type DWord -Value 0
Set-GPRegistryValue -Name $gpo.DisplayName -Key $au -ValueName AUOptions -Type DWord -Value 4
Set-GPRegistryValue -Name $gpo.DisplayName -Key $au -ValueName ScheduledInstallDay -Type DWord -Value 0
Set-GPRegistryValue -Name $gpo.DisplayName -Key $au -ValueName ScheduledInstallTime -Type DWord -Value 3
New-GPLink -Name $gpo.DisplayName -Target 'OU=Pilot Workstations,DC=homelab,DC=lan'
UseWUServer is the switch that matters most, because without it the client ignores WUServer and keeps talking to Microsoft. AUOptions 4 means download and install on a schedule, here every day (ScheduledInstallDay 0) at 03:00. Generate the GPO report to confirm the values map to the policies you expect:
[xml]$r = Get-GPOReport -Name 'WSUS - Pilot Workstations' -ReportType Xml
$r.GPO.Computer.ExtensionData.Extension.Policy | ForEach-Object { "{0} | {1} | {2}" -f $_.Category, $_.Name, $_.State }
Three enabled policies come back, which is the table above straight from the domain:
Windows Components/Windows Update/Manage end user experience | Configure Automatic Updates | Enabled
Windows Components/Windows Update/Manage updates offered from Windows Server Update Service | Enable client-side targeting | Enabled
Windows Components/Windows Update/Manage updates offered from Windows Server Update Service | Specify intranet Microsoft update service location | Enabled
The GPO only reaches computers inside that OU, so the client has to sit there. We joined our Windows 11 VM straight into it, running this on the client as an administrator after pointing its DNS at the domain controller, then restarted it:
Add-Computer -DomainName homelab.lan -NewName win11-pilot01 -OUPath 'OU=Pilot Workstations,DC=homelab,DC=lan' -Credential HOMELAB\Administrator -Force
Restart-Computer
Machines that are already domain members can be moved instead, with Get-ADComputer <name> | Move-ADObject -TargetPath 'OU=Pilot Workstations,DC=homelab,DC=lan' on the DC (we did not need that path in the lab), or you can link the GPO to the OU where they already are. Be aware of what you are linking: AUOptions 4 at 03:00 means the pilot machines install approved updates and restart on their own at night, even when nobody is logged on, so do not link it to an OU of machines that must never reboot unattended.
Step 7: Check That the Client Registered
On the client, refresh policy and confirm the GPO applied. /force reapplies every setting, not only the ones that changed, and /target:computer skips user policy.
gpupdate /target:computer /force
gpresult /r /scope computer
The WSUS GPO should be listed under applied objects. If it is missing, the computer object is in the wrong OU or the link is disabled:
Applied Group Policy Objects
-----------------------------
WSUS - Pilot Workstations
Default Domain Policy
Next, read the policy keys the GPO wrote and test the port. This catches two easy mistakes, a typo in the URL and a firewall in the way.
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' | Select-Object WUServer, WUStatusServer, TargetGroupEnabled, TargetGroup | Format-List
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' | Select-Object UseWUServer, AUOptions, ScheduledInstallDay, ScheduledInstallTime | Format-List
Test-NetConnection wsus01.homelab.lan -Port 8530 | Select-Object ComputerName, RemoteAddress, RemotePort, TcpTestSucceeded | Format-List
Our client had both URLs, the Pilot group, UseWUServer 1 and a working TCP connection to the server. If Test-NetConnection cannot even resolve the name, the problem is DNS rather than WSUS, and our guide to setting up a DNS server on Windows Server covers the zone side.
WUServer : http://wsus01.homelab.lan:8530
WUStatusServer : http://wsus01.homelab.lan:8530
TargetGroupEnabled : 1
TargetGroup : Pilot
UseWUServer : 1
AUOptions : 4
ScheduledInstallDay : 0
ScheduledInstallTime : 3
ComputerName : wsus01.homelab.lan
RemoteAddress : 10.0.1.20
RemotePort : 8530
TcpTestSucceeded : True
Now make the client check in. Since wuauclt /detectnow is gone, call the Windows Update agent through its COM object, which is the replacement Microsoft gives on the deprecation page, and then list the update services the agent knows about:
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
(New-Object -ComObject Microsoft.Update.ServiceManager).Services | Select-Object Name, IsDefaultAUService, IsManaged
Windows Server Update Service is now the default service and marked as managed, which proves the GPO took over from Windows Update:
Name IsDefaultAUService IsManaged
---- ------------------ ---------
DCat Flighting Prod False False
Windows Store (Prod) False False
Windows Server Update Service True True
Windows Update False False
Here are the same checks in short form, run again on win11-pilot01 after the policy refresh. Keep this trio handy for any machine that seems to ignore WSUS:

Back on the WSUS server, the client should appear after that scan, already filed into the Pilot group:
Get-WsusComputer -All | Format-Table FullDomainName, IPAddress, LastReportedStatusTime, ComputerTargetGroupIds
The second GUID in the group column is All Computers, which every client belongs to. The first one is Pilot, so client-side targeting did its job without anyone touching the console:
FullDomainName IPAddress LastReportedStatusTime ComputerTargetGroupIds
-------------- --------- ---------------------- ----------------------
win11-pilot01.homelab.lan 10.0.1.31 10/30/2026 4:48:51 AM {af2b9c91-f489-459e-9fd9-2baf6e7301d9, a0a08746-4dbe-4a37-9adf-9e7652c0b421}
One thing will look wrong in the console. WSUS listed our Windows 11 24H2 machine as “Windows 10 Enterprise Evaluation” in its OS column, while the version it stored was 10.0.26100, which is the Windows 11 24H2 build. When you build reports or filter computers by OS, filter on the build number and do not trust the product name in that column.
Step 8: Approve Updates for the Pilot Group
Nothing reaches a client until you approve it for one of its groups. The quickest honest list to start from is what your pilot machines already reported as needed, so ask WSUS for unapproved updates with that status:
Get-WsusUpdate -Approval Unapproved -Status FailedOrNeeded | Format-Table @{n='Title';e={$_.Update.Title}}, Classification, @{n='Needed';e={$_.ComputersNeedingThisUpdate}} -AutoSize | Out-String -Width 250
Out of 504 synced updates, our Windows 11 client needed three. That gap is the whole value of WSUS in one table, because the server, not the client, decides which of those three go out and when:
Title Classification Needed
----- -------------- ------
2026-10 Cumulative Update for .NET Framework 3.5 and 4.8.1 for Windows 11, version 24H2 for x64 (KB5127690) Security Updates 1
2026-10 Cumulative Update for Windows 11, version 24H2 for x64-based Systems (KB5127648) (26100.9711) Security Updates 1
Windows Malicious Software Removal Tool x64 - v5.146 (KB890830) Update Rollups 1
The client only showed up as needing anything after it reported in again. A fresh scan by itself did not refresh the console; the report arrived about two minutes after we triggered DetectNow() a second time. So if the Needed column stays empty right after a sync, give the clients a detection cycle before you assume they are fully patched.
Approve the list for the Pilot group only. Production gets the same updates later, after the pilot machines have run them for a few days:
Get-WsusUpdate -Approval Unapproved -Status FailedOrNeeded | Approve-WsusUpdate -Action Install -TargetGroupName 'Pilot' -Verbose 4>&1
With -Verbose you get one line per approval, and 4>&1 sends those lines into the normal output stream, which is handy in a scheduled script log:
Performing the operation "Approve-WsusUpdate" on target "2026-10 Cumulative Update for .NET Framework 3.5 and 4.8.1 for Windows 11, version 24H2 for x64 (KB5127690)".
Performing the operation "Approve-WsusUpdate" on target "2026-10 Cumulative Update for Windows 11, version 24H2 for x64-based Systems (KB5127648) (26100.9711)".
Performing the operation "Approve-WsusUpdate" on target "Windows Malicious Software Removal Tool x64 - v5.146 (KB890830)".
In the console the same thing is Updates > All Updates, filter on Unapproved and Failed or Needed, select the rows, right-click Approve and tick the Pilot group.
Approval is also the moment WSUS starts downloading update files, and this is where the disk sizing from the prerequisites becomes real. Those three approvals queued 13.71 GB of content on our server. You can watch it fill:
$p = (Get-WsusServer).GetContentDownloadProgress()
"{0:N2} of {1:N2} GB downloaded" -f ($p.DownloadedBytes/1GB), ($p.TotalBytesToDownload/1GB)
Until those files are on the server, the client has nothing to install. Our Windows 11 machine scanned again a minute after the approvals and still reported zero applicable updates, while WSUS had downloaded less than 1 GB of the 13.71 GB. About fifteen minutes after the approvals, with 8.79 GB on disk, the same scan from the client returned one update. This is the searcher we ran on the client for every scan in this guide. It asks the WSUS server for updates that are approved for this machine and not yet installed:
$sess = New-Object -ComObject Microsoft.Update.Session
$searcher = $sess.CreateUpdateSearcher()
$searcher.ServerSelection = 1
$t = Measure-Command { try { $r = $searcher.Search('IsInstalled=0 and IsHidden=0') } catch { $err = $_.Exception.Message } }
"Search took {0:N0} s" -f $t.TotalSeconds
if ($err) { "Search error: $err" } else { "ResultCode {0}, {1} updates applicable" -f $r.ResultCode, $r.Updates.Count; $r.Updates | ForEach-Object { $_.Title } }
The fourth run, with the .NET files already on the server, printed one title.
Search took 6 s
ResultCode 2, 1 updates applicable
2026-10 Cumulative Update for .NET Framework 3.5 and 4.8.1 for Windows 11, version 24H2 for x64 (KB5127690)
The .NET update’s files had finished, so WSUS offered it, while the Windows cumulative update was still downloading and stayed hidden from the client. That is the behaviour to expect after every Patch Tuesday approval: updates trickle out to clients as their content lands, not all at once. The download speed swung between roughly 0.15 and 0.8 GB per minute on our homelab link, so plan the first big approval round for a quiet evening.
Step 9: Keep WSUS Lean
A WSUS server needs housekeeping. Superseded and expired updates pile up month after month, and each one stays in SUSDB until something declines and removes it. Two jobs keep it healthy: a monthly cleanup and an occasional database reindex. Run the cleanup with a subset of what the Server Cleanup Wizard offers on the Options page (we left out the computers option, -CleanupObsoleteComputers, and -CompressUpdates):
Invoke-WsusServerCleanup -CleanupObsoleteUpdates -CleanupUnneededContentFiles -DeclineExpiredUpdates -DeclineSupersededUpdates
On our freshly synced server it finished in 3 seconds with nothing to do, which is the expected result on day one. One label even prints twice, so log the numbers over time rather than reading meaning into a single run:
Obsolete Updates Deleted:0
Expired Updates Declined: 0
Obsolete Updates Deleted:0
Diskspace Freed:0
Put that line in a monthly scheduled task, a few days after Patch Tuesday so superseded updates have had time to appear. Leave -DeclineSupersededUpdates out if some of your groups lag far behind and still install the older cumulative updates.
The reindex is the job most WSUS guides skip. SUSDB was already 220 MB in C:\Windows\WID\Data after a single sync of two products, and it only grows. Microsoft publishes the T-SQL for it on the Reindex the WSUS database page, run against the WID pipe \\.\pipe\MICROSOFT##WID\tsql\query. Note that sqlcmd was not on our fresh Server 2025 install, so you need the SQL Server command-line tools or SQL Server Management Studio on the box first.
What Broke in the Lab
Nothing in this build failed outright, but three things cost us time, and each one would make a new WSUS admin think the server was broken.
“Cannot save configuration because the server is synchronizing.”
The wizard shows this yellow bar on the Choose Upstream Server page when a sync is already running, and it will not save any page until that sync ends. We hit it because we had started the category sync from PowerShell first. Either let the sync finish, or stop it with (Get-WsusServer).GetSubscription().StopSynchronization() and run the wizard from the start. Do one or the other; mixing both routes on a fresh server only gets you this message.
“SqlException occurred. Number 50000 and message invalid update identity in XML”
During the first category sync, C:\Program Files\Update Services\LogFiles\SoftwareDistribution.log filled with warnings like this one, more than 30,000 of them before the log rolled over:
2026-10-30 04:46:26.054 UTC Warning WsusService.41 DBConnection.ExecuteCommandNoResult SqlException occurred. Number 50000 and message invalid update identity in XML for update 0C524D20-0816-0060-8A9E-0C4C490E4E54\200
They are logged at Warning level, and the sync still ended with Result : Succeeded. If you are tailing that log during the first sync, judge the run by the last sync result, not by the volume of warnings.
The client said it had nothing to install
Our first scan from the Windows 11 machine ran while the server was still on its category-only sync, before any update metadata existed. It took 237 seconds and came back with ResultCode 2 (succeeded) and zero applicable updates, which looks exactly like a fully patched machine. It was not. WSUS only offers a client the updates that are synced and approved for its group, so an empty WSUS produces a clean bill of health. Check the server side (Step 8) before you trust a client that reports nothing to do.