Monday, April 27, 2009

A Script to fix Windows Update Services clients not appearing in the WSUS console

After going through a bunch of patching solutions and being somewhat dissatisfied with most, I decided to give Microsoft's Windows Update Services another go. I hadn't used it since the 1.0 days and it was, well, rather 1.0 then.

WSUS 3.0 has a decent feature set, the two most desirable ones being a nice reporting system and the fact it's client is built into Windows (yes yes we can go back and forth on the merits or evil-ness of this fact, but its built in and therefore one less client I need to install...)

In our lab, this worked great. I have a setup where our load-balanced farms update and reboot several hours apart on saturdays, and our core boxes download but wait for manual updating. It was, in fact, one of the most flawless, hands-off setups I've worked with.

However, this was in the lab. In the real world, I ran into several issues. If you google for "WSUS clients not registering" or "WSUS clients disappear" you'll see a myriad of issues, several of which I came across. I won't post them here but the one that really irked me was this:

In production we have several hundred machines, most of which all show up in the WSUS console just fine. However, a few dozen were not appearing. There seemed to be no real commonality between them. They were a mix of 32-bit 2003, 64-bit 2003, and 64-bit 2008, some the "R2" editions of each. MS's "clientdiag.exe" tool passed on all. All the MS troubleshooting steps also confirmed access to the WSUS server. The "WindowsUpdate.log" showed no errors beyond normal transient ones.

Turns out, after much digging, I stumbled across this registry key:
hklm\software\microsoft\windows\currentversion\windowsupdate\susclientid

This, it seems, was the commonality of the several dozen machines. Each set of machines having issues (32-bit 2003 boxes, 64-bot 2003 boxes, 2008 boxes) had the same value as each other of the same time. Some investigation revealed these servers were clones of each other. While the technician that built them ran NewSID or sysprep'd them, this key didn't change. As a result, they'd check in to WSUS and conflict.

Now, this was only one of several issues I found. It seems every so often I bring a new box into the WSUS system to find it not working right away. I wrote the following script which so far addresses all of the issues I've come across. It works on both 32-bit and 64-bit 2003 and 2008:

@echo off
::Version 9.4.26 Aaron Dodd

echo Stopping Windows Update Services
net stop wuauserv >NUL

echo Deleting existing WSUS registry keys
:: This deletes the WSUS keys managed by GPO
reg delete hklm\software\policies\microsoft\windows\windowsupdate /f >NUL

:: This deletes WSUS ID's that should be different but can be the same if windows was installed via an image
reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v AccountDomainSid /f >NUL
reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v PingID /f >NUL
reg delete HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate /v SusClientId /f >NUL

echo Forcing policy update to restore registry keys
gpupdate /target:computer /force >NUL

echo Deleting existing local WSUS repository
del /s /q c:\windows\softwaredistribution >NUL
if exist c:\windows\syswow64 del /s /q c:\windows\syswow64\softwaredistribution >NUL

Echo Restarting BITS
net stop bits >NUL
net start bits >NUL

Echo Starting Windows Update Services
net stop wuauserv >NUL
net start wuauserv >NUL

Echo Forcing re-authorization to WSUS server and detection of patches
wuauclt /resetauthorization /detectnow >NUL

So far I haven't found a WSUS issue it hasn't fixed for me.

Note: this script does assume you're deploying WSUS settings via GPO. As a result, its safe to delete the entire policies...windowsupdate subkey because the GPO replaces it. Also, deleting "softwaredistribution" is safe because wuauserv ("Windows Update" service) recreates it.

The BITS part I'm not sure is necessary, but can't hurt ;-)

Also, yes, I'm stopping wuauserv again before starting it. It seems the GPO update sometimes starts it and since we just deleted the "softwaredistribution" folder, its necessary to stop/start the service again to rebuild it.

If you want to deploy this to many machines at once, I suggest using psexec.exe with the "-c" flag to copy this script and execute it on the target systems. I.e. save the script as "fix_wsus.cmd":

for %y in (svr1,svr2,svr3) do psexec.exe \\%y -c fix_wsus.cmd
See "for /?" for how to specify a text file of server names if you have a lot.