WSUS Administration, WSUSPool, web.config, settings enforcement via Configuration Items
Just in case you got here via other means, I recommend checking out this information as well, with links to more maintenance routines and information--> https://deploymentresearch.com/Research/Post/665/Fixing-WSUS-When-the-Best-Defense-is-a-Good-Offense
A recent new storm (see here, Jeff Carreon's blog) of Clients’ software update scanning issues had our team re-evaluating all of our existing wsuspool , web.config, and wsus administration settings on our Software Update points. As some of you CM Admins may recall, there has been multiple times over the last few years where due to various and assorted things outside of our control, like metadata size for Windows Updates, we as CM admins have had to manually adjust settings in WSUS configuration. At my company, we had a few Configuration Items enforcing and monitoring those settings, but not all of them.
The below settings may or may not be the ones which are the settings YOU have in your environment. You are free to take them and modify them for whatever makes the most sense for your particular configuration. For us, these are the settings we’ve determined we want to monitor and enforce… at least at this time. It seems like the settings required for a healthy SU scanning environment seem to change every 18 months—at least here—so don’t presume these settings are the end-all be-all of golden configuration. Everyone is different, and things change. But hopefully, if you do need to monitor or set these in your environment, these examples can assist you in getting to your Golden Configuration.
Keep in mind this blog is written from the standpoint of a System Center Configuration Manager person, who has created these rules using what is called “Configuration Items”. The way I structured it was One Rule Per Configuration Item, at my company. However, one could just as easily have created one Configuration Item—and have multiple rules inside it. It’s more personal preference than anything else in this case. In my case, since I was building and testing the rules one by one, I wanted a clear separation in case I messed something up while testing in the lab.
“The Easy Button” – I exported the rules from my lab, and they are available --> here <--. You can import them into your System Center Configuration Management console, and adjust or review them there, and test them. The exported rules are 14 CIs. To deploy them, you'd create a Baseline, add all 14 CIs to the Baseline. Prior to saving the Baseline, modify each rule to be "optional" instead of "required". Once saved, deploy the baseline to a test machine in "monitor" mode only--just to see what differences you might have. You may want to modify multiple rules, or discard some as not necessary for you to monitor/remediate. Once you are comfortable, deploy with 'remediation' and test again.
Occasionally, I’ve had requests to list out exactly what is inside each rule, usually because for whatever reason the import isn’t working as expected so the recipients can’t see what’s inside. So here is what is inside each Configuration Item… this will be long, but hopefully useful!
First of all, for each Configuration Item, I elected to make it an “Application” type. That because even though I’ve targeted the baseline just to the servers which I ‘know’ have the WSUS Feature installed, if someone were to accidentally deploy a baseline containing these rules to other devices, I want the CI to ‘not bother’ to run the CI test or remediation inside. It would be pointless and potentially confusing to people looking at reports. The “Detection” script for the Application is a Powershell Script type, this one line:
(Get-WmiObject -Namespace root\cimv2 -class win32_serverfeature -Filter "Name = 'WINDOWS SERVER UPDATE SERVICES'").Name
If anything is returned (the name), then the CI will assume the application is installed, and it will continue. If nothing is returned, it won’t continue.
Second, just about every single test requires the powershell model webadministration, using import-Module webadministration
Hopefully, your WSUS / Software Update point servers by default were installed with the add-windowsFeature Web-Server.Web-Scripting-Tools, but if you try to run these scripts interactively on a Software Update Point server, you get ‘failed to import webadministration module’, you’ll want to confirm that the web-scripting-tools component is installed—otherwise none of this will work.
Below are 14 Configuration Items we’re currently testing in our lab environment (will be moved to production once testing is complete). If you can’t import the .cab file attachment, worst case you can create your own Configuration Items using the below information.
CI 1 |
|
Title: |
WSUS Administration Max Connections Should be Unlimited |
Detection: |
import-Module webadministration ; (get-itemproperty IIS:\Sites\'WSUS Administration' -name limits.maxConnections.Value) |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\Sites\'WSUS Administration' -Name limits.maxConnections -Value 4294967295 |
Compliance Rule: |
4294967295 |
CI 2 |
|
Title: |
WSUS Administration MaxBandwidth should be unlimited |
Detection: |
import-Module webadministration ; (get-itemproperty IIS:\Sites\'WSUS Administration' -name limits.maxbandwidth.Value) |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\Sites\'WSUS Administration' -Name limits.maxBandwidth -Value 4294967295 |
Compliance Rule: |
4294967295 |
CI 3 |
|
Title: |
WSUS Administration TimeOut should be 320 |
Detection: |
import-Module webadministration (get-itemproperty IIS:\Sites\'WSUS Administration' -Name limits.connectionTimeout.value).TotalSeconds |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\Sites\'WSUS Administration' -Name limits.connectionTimeout -Value 00:05:20 |
Compliance Rule: |
320 |
CI 4 |
|
Title: |
WSUS ClientWebService web.config executionTimeout should be 7200 |
Detection: |
import-Module webadministration $FullFileName = (Get-WebConfigFile 'IIS:\Sites\WSUS Administration\ClientWebService').fullname [XML]$xml = Get-Content $FullFileName ((($xml.configuration).'system.web').httpRunTime).executionTimeout |
Remediation Script: |
import-Module webadministration $FullFileName = (Get-WebConfigFile 'IIS:\Sites\WSUS Administration\ClientWebService').fullname $acl = get-acl $FullFileName $ar = NewObject system.security.accesscontrol.filesystemaccessrule("NT Authority\SYSTEM","FullControl","Allow") $acl.SetAccessRule($Ar) Set-ACL $FullFileName $acl [XML]$xml = Get-Content $FullFileName $ChangeThis = ((($xml.configuration).'system.web').httpRunTime) $ChangeThis.SetAttribute('executionTimeout', '7200') $xml.Save($FullFileName) |
Compliance Rule: |
7200 |
|
NOTE: when setting the Compliance Rule, also check the box for “Report NonCompliance if this setting instance is not found”, because in some default installs of wsus, the web.config file doesn’t have this particular value at all. Checking that box there would ensure that it would be added if missing completely. |
CI 5 |
|
Title: |
WSUS ClientWebService web.config maxRequestLength should be 20480 |
Detection: |
import-Module webadministration $FullFileName = (Get-WebConfigFile 'IIS:\Sites\WSUS Administration\ClientWebService').fullname [XML]$xml = Get-Content $FullFileName ((($xml.configuration).'system.web').httpRunTime).maxRequestLength
|
Remediation Script: |
import-Module webadministration $FullFileName = (Get-WebConfigFile 'IIS:\Sites\WSUS Administration\ClientWebService').fullname $acl = get-acl $FullFileName $ar = NewObject system.security.accesscontrol.filesystemaccessrule("NT Authority\SYSTEM","FullControl","Allow") $acl.SetAccessRule($Ar) Set-ACL $FullFileName $acl [XML]$xml = Get-Content $FullFileName $ChangeThis = ((($xml.configuration).'system.web').httpRunTime) $ChangeThis.maxRequestLength = "20480" $xml.Save($FullFileName) |
Compliance Rule: |
20480 |
CI 6 |
|
Title: |
WSUS Service Should Be Running |
Detection: |
(Get-Service "WSUS Service").Status |
Remediation Script: |
Start-Service "WSUS Service" |
Compliance Rule: |
Running |
CI 7 |
|
Title: |
WSUSPool Application Pool Should be Started |
Detection: |
import-Module webadministration ; (Get-WebAppPoolState WSUSPool).Value |
Remediation Script: |
import-Module webadministration ; Start-WebAppPool -Name "WSUSPool" |
Compliance Rule: |
Started |
CI 8 |
|
Title: |
WSUSPool CPU ResetInterval should be 15 min |
Detection: |
import-Module webadministration ; (get-itemproperty IIS:\AppPools\Wsuspool -Name cpu.resetInterval.value).minutes |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\AppPools\Wsuspool -Name cpu -Value @{resetInterval="00:15:00"} |
Compliance Rule: |
15 |
CI 9 |
|
Title: |
WSUSPool Ping Disabled |
Detection: |
import-Module webadministration ; (get-itemproperty IIS:\AppPools\Wsuspool -Name processmodel.pingingEnabled).value |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\AppPools\Wsuspool -Name processmodel.pingingEnabled False |
Compliance Rule: |
False |
CI 10 |
|
Title: |
WSUSPool Private Memory Limit should be 0 |
Detection: |
import-module webadministration $applicationPoolsPath = "/system.applicationHost/applicationPools" $appPoolPath = "$applicationPoolsPath/add[@name='WsusPool']" (Get-WebConfiguration "$appPoolPath/recycling/periodicRestart/@privateMemory").Value
|
Remediation Script: |
import-module webadministration $applicationPoolsPath = "/system.applicationHost/applicationPools" $appPoolPath = "$applicationPoolsPath/add[@name='WsusPool']" Set-WebConfiguration "$appPoolPath/recycling/periodicRestart/@privateMemory" -Value 0
|
Compliance Rule: |
0 |
CI 11 |
|
Title: |
WSUSPool queueLength should be 30000 |
Detection: |
import-Module webadministration ; (get-itemproperty IIS:\AppPools\Wsuspool | Select queuelength).queueLength |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\AppPools\Wsuspool -name queueLength 30000 |
Compliance Rule: |
30000 |
CI 12 |
|
Title: |
WSUSPool RapidFail Should be Disabled |
Detection: |
import-Module webadministration ; (get-itemproperty IIS:\AppPools\Wsuspool -name failure.rapidFailProtection).Value |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\AppPools\Wsuspool -name failure.rapidFailProtection False |
Compliance Rule: |
False |
CI 13 |
|
Title: |
WSUSPool Recycling Regular Time interval should be 0 |
Detection: |
import-Module webadministration ; ((get-itemproperty IIS:\AppPools\Wsuspool -name recycling.periodicRestart.time).Value).TotalMinutes |
Remediation Script: |
import-Module webadministration ; set-Itemproperty IIS:\AppPools\Wsuspool recycling.periodicRestart.time -Value 00:00:00 |
Compliance Rule: |
0 |
CI 14 |
|
Title: |
WSUSPool requests should be 0 |
Detection: |
import-module webadministration $applicationPoolsPath = "/system.applicationHost/applicationPools" $appPoolPath = "$applicationPoolsPath/add[@name='WsusPool']" (Get-WebConfiguration "$appPoolPath/recycling/periodicRestart/@requests").Value
|
Remediation Script: |
import-module webadministration $applicationPoolsPath = "/system.applicationHost/applicationPools" $appPoolPath = "$applicationPoolsPath/add[@name='WsusPool']" Set-WebConfiguration "$appPoolPath/recycling/periodicRestart/@requests" -Value 0
|
Compliance Rule: |
0 |
- Created on .