WSUS complete setup. While there is another article that preceeds, this article tries to encompass the full WSUS setup, configuration, maintenance and common problems that you may run into.
There are 6 parts to this:
- WSUS Setup
- WSUS Configuration
- WSUS Maintenance
- WSUS Client Update
- WSUS Client Problems
- WSUS Problems
1-WSUS Setup
https://www.youtube.com/watch?v=6RFkP2wppOI
Powershell Module
As a refresher, you can see your PowerShell modules with:
get-module
Or see the installed PowerShell modules:
get-installedmodule
Or see all the available PowerShell moduels:
get-module -listavailable
UpdateServices
There is a built-in PowerShell module that installs with WSUS called UpdateServices. This module can be used for many WSUS commands.
To see the commands:
get-command -module UpdateServices
The main command is:
Get-WSUSUpdate
Get-WSUSUpdate -Classification Critical -Status Any -Approval unapproved |get-member
Get-WSUSUpdate -Classification Critical -Status Any -Approval unapproved |select products -unique
Classifications
WSUS updates has Classifications.
There is a slight variation in Classifications from WSUS server in certain places:
[enum]::GetNames([Microsoft.UpdateServices.Commands.WsusUpdateClassifications])
Classification only includes:
All
Critical
Security
WSUS
This is different than the WSUS Classifications listed here as "Root Categories":
Get-WsusServer |Get-WsusClassification
Classifications includes:
Applications
Critical Updates
Definition Updates
Driver Sets
Drivers
Feature Packs
Security Updates
Service Packs
Tools
Update Rollups
Updates
Upgrades
Each update also has a Category. To see the Language Packs from the client:
Get-WindowsUpdate -Category "Language packs"
See here for Update Categories:
https://learn.microsoft.com/en-us/archive/blogs/dubaisec/windows-update-categories
2-WSUS Configuration
From above, there is a built-in PowerShell module that installs with WSUS called UpdateServices.
-Get-Command -Module UpdateServices
-Get-WSUSServer
-Get-WSUSComputer
Configuration can be done automatically or it can be done manually. We will go through both.
Manual Configuration (aka the hard way)
-IIS > WSUS Application Pool > "Advanced Settings"
-Queue Length: 25000 from 10000
-Limit Interval (minutes): 15 from 5
-"Service Unavailable" Response: TcpLevel from HttpLevel
-Private Memory Limit: 5529600 from 1843200 (or 0 for unlimited)
-(Stop the IIS first) > Edit the web.config ( C:\Program Files\Update Services\WebServices\ClientWebService\web.config ) for WSUS
-Replace <httpRuntime maxRequestLength="4096" /> with <httpRuntime maxRequestLength="204800" executionTimeout="7200"/>
-Restart-WebAppPool -name wsuspool
-Get-WsusUpdate -Approval Unapproved -Status Needed
-Get-WsusUpdate -Approval Unapproved -Status Needed |Approve-WsusUpdate -Action Install -TargetGroupName “All Computers” –Verbose
-Get-WsusServer | Invoke-WsusServerCleanup -CleanupObsoleteComputers –CleanupObsoleteUpdates -CleanupUnneededContentFiles -CompressUpdates -DeclineExpiredUpdates -DeclineSupersededUpdates
-download: https://docs.microsoft.com/en-us/troubleshoot/mem/configmgr/reindex-the-wsus-database
-database is WID located in: C:\Windows\WID\Data > called SUSDB.mdf
-sqlcmd -S np:\\.\pipe\MICROSOFT##WID\tsql\query -i C:\installs\WsusDBMaintenance.sql
To see the WSUS configuration settings:
-reg query "HKLM\SOFTWARE\Microsoft\Update Services\Server\Setup"
-options set to auto-approve > ran rule.
-created gpos for workstations/servers: https://community.spiceworks.com/how_to/1390-wsus-gpo-settings-for-the-real-world?page=3
Automatic Configuration
This will automatically set the configuration for you.
Get the Optimize-WsusServer script:
wget https://github.com/awarre/Optimize-WsusServer/blob/master/Optimize-WsusServer.ps1 -outifle Optimize-WsusServer.ps1
Install-Module SqlServer -allowclobber
.\Optimize-WsusServer.ps1 -FirstRun
.\Optimize-WsusServer.ps1 -DeepClean
Increase the transfer request quantity
When a WSUS client asks for an update, it can error out (0x80244010) if the transfer is over the limit.
To set the limit to unlimited:
sqlcmd -S np:\\.\pipe\MICROSOFT##WID\tsql\query
USE SUSDB
GO
SELECT MaxXMLPerRequest from tbConfigurationC
GO
UPDATE tbConfigurationC SET MaxXMLPerRequest = 0
GO
To reset to the default value:
UPDATE tbConfigurationC SET MaxXMLPerRequest = 5242880
GO
Language Pack Configuration Caveat
WSUS console shows Language Pack (ie KB2839636, KB3012997) not installed.
This is working as designed. Whether to install a language pack is up to each user account to decide if the a language pack should be installed or not.
As a result, language packs should not be deployed by WSUS as there will non-compliant reports coming back to WSUS.
The following will deny all Language Packs in WSUS that have not been Approved:
get-WsusUpdate |?{$_.update.title -like "*Language Pack*"} | Deny-WsusUpdate
If the Language Packs were already Approved, then the following will deny all Language Packs:
get-WsusUpdate -Approval Approved -Status FailedOrNeeded |?{$_.update.title -like "*Language Pack*"} |Deny-WsusUpdate
(This works because we know that update package is failing/needed.)
Note that the Language Packs are not included in the normal update process. Meaning if you search for updates on the Windows client, the Language Pack does not show. But it will show as missing on the WSUS report.
3-WSUS Maintenance
If this is your first time, Maintenance can be complicated as there are many ways to go about doing so without any real official way of doing so from Microsoft. The Microsoft published articles on WSUS are questionable as well. There are simply better methods.
You can fiddle around with WSUS for hours/days/weeks/months and even years. Sometimes I find some people who equate WSUS with being a sysadmin.
I put all the ways to peform WSUS Maintenance in its own article since it would make this too long:
http://www.daknetworks.com/blog/655-seven-way-wsus-maintenance
For a "speedrun" to get WSUS working as fast as possible, there is a script in PowerShell Gallery called Wsus-Maintenance and Invoke-DGASoftwareUpdateMaintenance.ps1
Install-Script -Name Wsus-Maintenance
Wsus-Maintenance (to see the readme)
Wsus-Maintenance -Run
.\Invoke-DGASoftwareUpdateMaintenance.ps1 -configfile .\config_wsus_standalone.ini
.\Invoke-DGASoftwareUpdateMaintenance.ps1 -configfile .\config_wsus_standalone.ini #uncomment whatifpreference
Plugins:
Decline-Edge
Decline-Office365Editions
Decline-Windows10Languages
Decline-Windows10Versions
Decline-Windows11Languages
Decline-WindowsARM64
Decline-WindowsItanium
.\Decline-SupersededUpdates.ps1 -SkipDecline -UpdateServer localhost -port 8530
.\Decline-SupersededUpdates.ps1 -UpdateServer localhost -port 8530 #remove -SkipDecline
Get-WSUSUpdate -Status Any -Approval unapproved |?{$_.products -match "2003" -or $_.products -match "2007" -or $_.products -match "2010" -or $_.products -match "2013"} |Deny-WsusUpdate -verbose #accidentially downloaded office 2003, 2007, 2010, 2013 |
Get-WSUSUpdate -Status Any -Approval unapproved |?{$_.products -match "Windows 10 and later Dynamic Update" -or $_.products -match "Windows 10 and later Dynamic Update, Windows Safe OS Dynamic Update" -or $_.products -match "Windows 10 and later GDR-DU" -or $_.products -match "Windows 10 GDR-DU FOD" -or $_.products -match "Windows 10 Feature On Demand" -or $_.products -match "Windows 10 LTSB, Windows 10" -or $_.products -match "Windows GDR-Dynamic Update"} |Deny-WsusUpdate -verbose
Get-WSUSUpdate -Classification critical -Status Any -Approval unapproved |Approve-WsusUpdate -Action Install -TargetGroupName "All Computers" –Verbose
Get-WSUSUpdate -Classification security -Status Any -Approval unapproved |Approve-WsusUpdate -Action Install -TargetGroupName "All Computers" –Verbose
4-WSUS Client Update
On the client a PowerShell module called PSWINDOWSUPDATE can be used.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-Module PSWindowsUpdate
Get-ExecutionPolicy
Set-ExecutionPolicy RemoteSigned
Import-Module PSWindowsUpdate
get-command -module pswindowsupdate
get-wuinstallerstatus
get-wurebootstatus
get-wuinstall -verbose (This is the same as: Get-WindowsUpdate or Get-WindowsUpdate -Verbose)
get-wuinstall -verbose -install (This is the same as Install-WindowsUpdate)
get-command -module pswindowsupdate
Windows Update Repo
To see the source repository of the updates (ie local intranet WSUS server or public internet Microsoft server):
Get-WUServiceManager
To set the source of the update to the public internet Microsoft Server:
Get-WindowsUpdate -MicrosoftUpdate
Extra
To search for a specific update:
Get-WindowsUpdate -KBArticleID KB982861
Get-WindowsUpdate -KBArticleID "KB5002324", "KB5002325"
Get-WindowsUpdate -KBArticleID KB982861 -Verbose
To get the current Job:
Get-WUJob
To get the history:
Get-WUHistory | ?{$_.Description -like "*Update*"}
5-WSUS Server Reset
Reset WSUS Pool
If WSUS Server Keeps Stopping
Internet Information Services (IIS) Manager -> Server -> Application Pools -> Select “WSUSPool” -> Actions Advanced -> Recycling -> change “Private Memory Limit (KB)“.
-set to 0 (no limit).
-started WSUSPool.
-started Windows WSUS service.
-started cleanup.
Reset WSUS Server
If you run into WSUS problems you can reset the WSUS server:
net stop wsusservice
"c:\Program Files\Update Services\Tools\wsusutil.exe" reset
net start wsusservice
Reset WSUS View
-reset view:
-close mmc wsus
-rm %userprofile%\application data\Microsoft\MMC\wsus
6-WSUS Client Problems
Check the Windows Client is Using WSUS Server
See if settings are being applied to the client system:
via PSWindowsUpdate:
Get-WUSettings
via gpo inspection:
gpresult /r /scope:computer
rsop.msc
Configuration\Administrative Templates\Windows Components\Windows Update
via reg query:
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate
Check the Windows Client is Reaching the WSUS Server
Now check to see if the client can update:
via manual download:
http://<FQDN-of-WSUSServerName>:8530/Selfupdate/iuident.cab
If you are prompted to download the file, this means that the client can reach the WSUS server and it is not a connectivity issue.
via log inspection:
wuauclt /detectnow
get-content %SystemRoot%\WindowsUpdate.log
get-content %SystemRoot%\WindowsUpdate.log |findstr /i "server:"
If the intranet WSUS server shows, then it is reaching the correct server.
If not, then there might be a connectivity issue with the Anonymous user account called IUSR:
IIS > Virtual Directory > SelfUpdate > Authentication > Enable Anonymous Authentication
IUSR is the anonymous/www user
(No longer uses the IUSR_<MachineName>)
Check the Windows Client is Updating
Now check what happens when the client tries to update:
get-content %SystemRoot%\WindowsUpdate.log -wait
get-content %SystemRoot%\WindowsUpdate.log -wait -tail 25
Error 0x800f0823
The update error 0x800f0823 usually happens when a recent servicing stack update (SSU) is missing. The SSU is the update agent. Confirm by looking at the CBS log:
get-content %SystemRoot%\Logs\CBS\CBS.log |findstr /i hresult
get-content %SystemRoot%\Logs\CBS\CBS.log |findstr -wait -tail 25
This is where PDQ can help and be part of the patch management. PDQ can auto download and push the monthly rollup to the clients. But it's 2023 and the Windows Server 2012 R2 hasn't been patched since... well, you know. So it needs a bit of help.
Service Stack Update (SSU)
The Service Stack Update is the update agent itself. So it is kinda like updating YUM. Let's update the SSU.
Get the newest SSU here:
https://msrc.microsoft.com/update-guide/en-us/vulnerability/ADV990001
wget https://catalog.s.download.windowsupdate.com/c/msdownload/update/software/secu/2022/10/windows8.1-kb5018922-x64_3aa7832b7586e11304f8fee5e09b6829b32d1833.msu -outfile "Win8.1AndW2K12R2-KB3191564-x64.msu"
wusa.exe "Win8.1AndW2K12R2-KB3191564-x64.msu" /log:"/myLogFile.log"
CBS.log shows:
Trusted Installer is shutting down because: SHUTDOWN_REASON_AUTOSTOP
[HRESULT = 0x800f0805 - CBS_E_INVALID_PACKAGE]
Reset WindowsUpdateAgent
Now let's reset the WindowsUpdateAgent:
via PSWindowsUpdate:
Reset-WUComponents
via Cleanup Manager:
cleanmgr
-select Windows Updates to clean out the updates.
-wait about an hour
via manual:
https://support.microsoft.com/en-us/sbs/windows/fix-windows-update-errors-18b693b5-7818-5825-8a7e-2a4a37d6d787
net stop cryptsvc
net stop bits
net stop wuauserv
ren %systemroot%\softwaredistribution softwaredistribution.bak
ren %systemroot%\system32\catroot2 catroot2.bak
net start cryptsvc
net start bits
net start wuauserv
Reset Windows Update Components
The Windows Update needs reset. First let's verify the OS:
DISM /Online /Cleanup-Image /RestoreHealth
reboot
It may reboot on it's own a second time.
sfc /scannow
reboot
0x80244010 - Just Retry a Bunch of Times
Finally, start the update process again and it should go through. If the error message is 0x80244010, then just RETRY. You might have to RETRY about 10 times. You are hitting the limit on what can be done on WSUS (200). RETRYING picks up where it left off. This is why it needs to be done multiple times.
If configurated correctly, this shouldn't happen. See the 2-WSUS Configuration -> Increase-the-transfer-request-quantity
Force Windows Client Report to WSUS
Sometimes the Windows Client won't report to WSUS. Let's force it:
$updateSession = new-object -com "Microsoft.Update.Session"; $updates=$updateSession.CreateupdateSearcher().Search($criteria).Updates
wuauclt /reportnow
Or if you need to fully reset the WSUS client:
-remove WSUS client from WSUS
-on the WSUS client, remove the settings and reset the Update Components:
echo y |REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\" /v SusClientId
echo y |REG DELETE "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\" /v SusClientIdValidation
Reset-WUComponents
WUAUCLT /ResetAuthorization /DETECTNOW
For a in-depth article on WSUS Clients not updating see the following:
http://www.daknetworks.com/blog/653-server-2019-not-updating-cumulative-update--wsus-cumulative-update
NOTES:
Someone suggested that patch Tuesday doesn't exist because patches are sometimes released afterwards and that Tuesday isn't the same across the globe. It was a very long thread and there is some validity. Even VMware went to UTC on the logs and doesn't allow it to be changed to the local timezone. Probably smart. In any event, here is some date/time to narrow Windows Update no matter where you are in the world:
(get-date).ToUniversalTime()
(get-date).DayOfYear
[int](Get-Date -UFormat %s -Millisecond 0)
([DateTimeOffset](Get-Date)).ToUnixTimeSeconds()