WSUS vs Windows 7/ Windows 8.1 client issues

We’ve recently needed to be a bit more rigorous about using WSUS, so I started off on our servers and found out that if you go with “Scheduled Installs”, what this means is that any given server can reboot pretty much when it likes with up to 30 minutes grace.

This was no good at all, so I started using a PowerShell script to do the WSUS side of things, then used a server to run scheduled tasks against a group of servers at a time. This meant that we could reboot the servers when we liked, which is around 04:00.

This was all ticking along nicely, so we opened this out to a select number of clients- mix of Windows 7 Pro SP1 and Windows 8.1 Pro. Very little happened. PCs didn’t get patched, running WSUS through the GUI resulted in the progress bar looping, PowerShell didn’t work, the Event Viewer only displayed errors and WSUS itself complained the PCs hadn’t reported for a long time, or maybe not at all.

After a week of fiddling about with the Windows Update client, deleting registry keys, deleting WindowsUpdate.log etc etc, turns out it seems there are 2 KB articles- KB3138612 & KN3138615- that appear to be critical to getting WSUS working on clients. These KBs relate to “updates for Windows Update” dated March 2016.

The long and the short of it is that it appears the best way to get Windows 7 & 8.1 working is to start from scratch: reinstall Windows from a DVD and then immediately install the relevant KB .msu file.

I tried pointing freshly-built clients at WSUS (before installing the KB) and they either just looped (Windows 8.1) or told you to install an update to Windows Update (Windows 7). This build under Windows 8.1 wouldn’t even talk to WSUS until I’d installed the KB, and I assumed the Windows 7 Windows Update Client Update was the right KB article, although it didn’t say.

I now have 3 new Windows 8.1 images: the OS by itself, the OS with KB3138615 and the OS with all available updates from WSUS. I’m doing the same thing for Windows 7. Unfortunately, this means our existing SCCM images are “fine” in that they’re patched, but it looks like they can’t talk to WSUS so our choice is either to talk to Microsoft to fix this, or re-image all our PCs with the new images. This isn’t my call, but is seriously annoying to find out when we’ve just gone around using SCCM to apply images to PCs whic won’t actually update on a day-to-day basis.

Microsoft KB3124557: MS16-010: Security update in Microsoft Exchange Server to address spoofing: January 12, 2016

First thing to be aware of is that this update definitely does come down through WSUS, which was my first mistake (I’m so used to Exchange updates being full-blown CUxx-style, download-the-entire-ISO-again that I didn’t expect this to show up).

We have a 3-node DAG, and of course I hit “install all updates” on all 3 nodes. Meaning Exchange services got disabled (and I mean disabled. not just stopped) on all nodes. My thinking for this was that as Node 1 wasn’t managing any mailbox databases, I could patch it (not realising it had an Exchange update), reboot it, move some DBs, then reboot the other two nodes one at a time, juggling DBs as necessary.

Once I saw what was going on, I cancelled the update which is a bad idea, because it neither continued to install the patch nor rolled back the patch by re-enabling and starting Exchange services. So after cancellation, I had 3 nodes, none of which had the patch and all of which had Exchange disabled.

At this point, my “bads” were a) I should have checked whether the updates included anything for Exchange and b) not cancelled the update jobs.

To make matters worse, I’ve got 2 mailboxes but they’re both in the same mailbox database, and this database was on mounted on Node 3 which still had all of its services disabled. So when I logged on to ECP with my admin account, all I got was a blank screen.

After raising an incident, and then getting a phone call from Microsoft (http://support.microsoft.com/oas) it turns out that basically all I had to do was switch all the services to automatic on Node 3, and then start them. Suddenly, I could get to ECP, my mailboxes were accessible etc etc (and yes, I should have been using PowerShell, not ECP).

SCCM: build and capture with installed updates

<sigh>

Yet again, I’ve been chasing my tail with SCCM. I know my (extremely limited sub-set) Windows 7 updates package was working and downloaded, and deployed etc. I know my Build and Capture was working. But I couldn’t get updates to install as part of the build and capture process. I could build and capture a WORKGROUP machine no problem, because the SYSPREP stage requires WORKGROUP membership. I could build and capture- and update- a domain machine but this would fail to capture because SYSPREP wouldn’t work.

In the end, this link- http://bit.ly/1kWoiJ5 – said it all. Under the “Setup Windows and Configuration Manager” section, just add SMSSLP=yourserver.yourdomain.com under the “Installation properties” section. If the build machine is on the domain, it can use AD/ DNS to locate the SCCM server. If it’s in a workgroup, it needs to be told explicitly where to find services- hence adding the property above. Thanks to Mathias Haas for this, it was driving me around the bend.

UPDATE 15AUG2014:

<sigh>

Yes, this was me being stupid. As this thread explains- http://www.windows-noob.com/forums/index.php?/topic/11126-system-center-configuration-manager-2012-build-and-capture-with-updates-gold-image/- I’d just forgotten to redistribute everything. Seemples.

Putting the GUI back onto Core

This problem has- unfortunately- reverted back to injecting update files into a WIM file, which isn’t ideal but c’est la vie.

The best process I’ve come up with is this: use PowerShell to pull up a list of all updates applied to a server; modify this list to turn it into a batch file that can search c:\windows \softwaredistribution\downloads and then output this list to a text file; copy this text file to another batch file, modify this copy so that DISM applies each update to the mounted WIM in sequence.

If nothing else this process is time consuming. I’ve currently got my 2nd batch file applying each update then pausing (in case of a failure), then committing each update to disk to minimise loss in the event of a problem. Hopefully this whole process can be automated, but bear in mind this is only applying about 50 updates to 1 WIM image- there are way more updates than that, and 2 images, plus keeping the master images patched… not the most streamlined process.

UPDATE 21/FEB/14: it’s even worse. I’ve got a stable method for retrieving updates, but the actual DISM commands stop working after a while- this is completely random, but at some point the Add-Package commands stop working and then corrupts the install.wim file, at which point you have to scrap it all and start again. My (final?) method is to mount the WIM image, apply the update, dismount the WIM image, mount the WIM image, apply the update, dismount the WIM image… this is going to take ages. It’s been running for an hour now and has done 5 updates- hopefully there’ll be some good news by the time I get back to it on Monday.

UPDATE 12/MAR/2014: Injecting updates into the WIM seems to be the one and only way of getting this to work (although I haven’t actually tried installing the GUI yet, this is just the official MS line). Anyway, here’s the procedure if using WSUS:

  • Build a server as core;
  • Join it to the domain;
  • DON’T install any WSUS updates just yet;
  • copy everything from C:\Windows\SoftwareDistribution\Downloads to some temporary location;
  • Run a “dir /s /b *.cab” against the folder you just copied and >> the text to file- this should give you a list of all the updates with their path;
  • Knock up a quick batch file using the contents of the above batch file as follows:
  • Dism /Mount-WIM /WimFile:C:\Support\Copy\install.wim /Index:2 /mountdir:C:\Support\WIM
  • dism.exe “/Image:c:\Support\WIM” /LogPath:C:\Support\dism.log /LogLevel:4 /Add-Package “/PackagePath:C:\Support\Cabs1f8571c8b1da3d1952869019dbc51ab\windows8-rt-kb2916036-x64.cab”
  • IF %ERRORLEVEL% NEQ 0 GOTO END
  • dism.exe /Unmount-Wim /MountDir:c:\Support\WIM /commit
  • copy C:\Support\Copy\install.wim C:\Support\Copy\backup.wim /y
  • The theory being that you mount the WIM, patch it, check to see if the patch failed, if not dismount the WIM, back it up and start again. This is massively convoluted, I’ll post back when I’ve had a chance to test it in anger.

KB2837618 and KB2837643

I don’t quite know what’s going on yet, but it looks like Microsoft have had another outing with the above updates.

We know the security update 28387618 kills Outlook 2013; what’s unclear is the part 2837643 plays. It looks like, somehow, 2837643 is the “master” update which somehow also installs 2837618; ?. We’ve also had a lot of people complaining about Out-Of-Office not working which I’ve also found, whether this is anything to do with these 2 updates is unknown as yet.

I’ve just built a new W7 PC with Office 2013 and am patching it now (minus these two). Then it’ll be a case of  applying different combinations of the two above updates manually to see what happens.

UPDATE 22/11/2013. It’s not looking good for these updates. My W7 test machine has Office, but not the above two updates. I can open up Out-Of-Office on this one, simultaneously try it on my W8 machine (which does have the updates) and it doesn’t open on the W8 one. So… it’s looking likely that these updates can (a) cause Outlook to crash and (b) prevent access to Out-Of-Office.

Powershell menu to perform WSUS tasks

After my previous post, WSUS is actually a bit more complicated than I’d thought so I’ve developed an entire, stand-alone WSUS script because that previous one was getting quite big.

A couple of notes: the location of the log files aren’t really important, when I started with the script it was just listing the updates inside the PowerShell windows which wasn’t very visually friendly. So I stuck them in a text file to make it easier to read. The other thing is, it doesn’t seem to run properly immediately after a reboot- I don’t know if this is just my Server Core 2012 VM being a bit sluggish, but it just does nothing if you run it within 5 or 10 minutes of rebooting. But it does work, and I’ve kept an eye on our WSUS Server and it now has all relevant updates installed.

Oh great. All the formatting has gone as well. Sorry about that, it was neatly tabbed before…

EDIT 17-MAY-2013: After some problems with my main W8 host, I’ve modified the script below to remove the option not to reboot (which I’m not sure worked anyway). So now the script automatically reboots after running a batch of updates. I’ve left the code in for interest, but would strongly advise removing the lines highlighted in red below.

======================================================================================================================================================================================
#Split in to three main sections: first of all just searches for updates, next option is to install, then final option is to display installed updates

#Equivalent to DOS CLS- just wipes the console screen
Clear-Host

#Sets the menu up- this is a 4-option menu
$menuText=”1) Display new (not yet installed) updates in Notepad”,”2) Download and install new updates”,”3) Display installed updates in Notepad”,”4) Quit”

#Displays the menu options
$menuText

do
{
#Starts the menu system- asks for user to make a choice
switch ($chooseOption=Read-Host -Prompt “Please choose your option”)
{
1 {
#Deletes the old log file- this stops the log file displaying false (too many) updates
Remove-Item C:\Support\new_WSUS_Patches.log
#Defines update criteria
$newUpdateCriteria = “IsInstalled=0 and Type=’Software'”
#Search for new updates.
$newUpdateSearcher = New-Object -ComObject Microsoft.Update.Searcher
$newSearchResults = $newUpdateSearcher.Search($newUpdateCriteria)
#Catches 0 updates error, gracefully exists when there are no new updates
If ($newSearchResults.updates.Count -eq 0) {
Clear-Host
Write-Host “I couldn’t find any updates…”
Start-Sleep 5
}
Else {
#This just performs the search, outputs the results to a text file and then opens the text file
$newSearchResults.Updates | ForEach-Object {Out-File -FilePath C:\Support\new_WSUS_Patches.log -Append -InputObject $_.Title }
Invoke-Item C:\Support\new_WSUS_Patches.log
}
cls
$menuText
}
2 {
#Define update criteria.
$newUpdateCriteria = “IsInstalled=0 and Type=’Software'”
#Search for new updates.
$newUpdateSearcher = New-Object -ComObject Microsoft.Update.Searcher
$newSearchResults = $newUpdateSearcher.Search($newUpdateCriteria)
If ($newSearchResults.updates.Count -eq 0) {
Clear-Host
Write-Host “I couldn’t find any updates…”
Start-Sleep 5
cls
$menuText
}
Else {
#Download updates.
$Session = New-Object -ComObject Microsoft.Update.Session
$Downloader = $Session.CreateUpdateDownloader()
$Downloader.Updates = $newSearchResults.Updates
$Downloader.Download()

#Install updates.
$Installer = New-Object -ComObject Microsoft.Update.Installer
$Installer.Updates = $newSearchResults.Updates
$installUpdates = $Installer.Install()
#Reboot if required by updates.
If ($Result.rebootRequired) {
Clear-Host
Write-Host “This computer needs to be restarted so will do so in 1 minute”
Start-Sleep 60
Restart-Computer
}
Else {
Clear-Host
Write-Host “Reboot NOT required!”
Start-Sleep 5
cls
$menuText
}
}
}
3 {
#Deletes the old log file
Remove-Item C:\Support\installed_WSUS_Patches.log
#Define update criteria.
$installedUpdateCriteria = “IsInstalled=1 and Type=’Software'”
#Search for installed updates.
$installedUpdateSearcher = New-Object -ComObject Microsoft.Update.Searcher
$installedSearchResults = $installedUpdateSearcher.Search($installedUpdateCriteria)
$installedSearchResults.Updates | ForEach-Object {Out-File -FilePath C:\Support\installed_WSUS_Patches.log -Append -InputObject $_.Title }
Invoke-Item C:\Support\installed_WSUS_Patches.log
cls
$menuText
}
4 {Break}
}
#As soon as the user preses 4, the script exits
} while ($chooseOption -ne 4)