Fix for Windows Server 2016 Stuck at “Downloading 0%” from WSUS server – UpdateServiceUrlAlternate Registry Key

I ran into an issue recently with our Windows Server 2016 servers not installing their updates. Instead, all our 2016 servers would get stuck with the message “Updates are available. Downloading updates 0%” however they would never actually download the updates. These servers were configured to our WSUS server, which was also a Server 2016 machine.

The first thing I investigated was to look at the logs on the client server. I tried using the Get-WindowsUpdateLog cmdlet in Powershell, however, the log that was generated was useless because every line had no date and no format information (what the hell, Microsoft!). The logs look like this:

1601/01/01 09:30:00.0000000 872   1104                  Unknown( 39): GUID=50a5ef43-b2b6-3c52-145b-a386d8769665 (No Format Information found).
1601/01/01 09:30:00.0000000 872   1104                  Unknown( 38): GUID=50a5ef43-b2b6-3c52-145b-a386d8769665 (No Format Information found).
1601/01/01 09:30:00.0000000 872   1104                  Unknown( 34): GUID=7b9bf239-47b9-3688-3a9e-14f09f262608 (No Format Information found).
1601/01/01 09:30:00.0000000 872   1104                  Unknown( 39): GUID=50a5ef43-b2b6-3c52-145b-a386d8769665 (No Format Information found).
1601/01/01 09:30:00.0000000 872   1104                  Unknown( 38): GUID=50a5ef43-b2b6-3c52-145b-a386d8769665 (No Format Information found).
1601/01/01 09:30:00.0000000 872   1104                  Unknown( 34): GUID=7b9bf239-47b9-3688-3a9e-14f09f262608 (No Format Information found).
1601/01/01 09:30:00.0000000 872   1104                  Unknown( 39): GUID=50a5ef43-b2b6-3c52-145b-a386d8769665 (No Format Information found).

However, after investigating the registry keys on one of our servers, I saw a new registry key that I didn’t recognise, UpdateServiceUrlAlternate. See this dump from Powershell:

PS C:\Users\me\Desktop> ls HKLM:\SOFTWARE\Policies\Microsoft\Windows\


    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows


Name                           Property
----                           --------
Appx
BITS                           EnableBitsMaxBandwidth     : 0
                               MaxBandwidthValidFrom      : 9
                               MaxBandwidthValidTo        : 17
                               MaxTransferRateOnSchedule  : 1000
                               MaxTransferRateOffSchedule : 9999
CurrentVersion
DataCollection
EnhancedStorageDevices         TCGSecurityActivationDisabled : 0
IPSec
Network Connections            NC_PersonalFirewallConfig : 0
NetworkConnectivityStatusIndic (default) :
ator
NetworkProvider
safer
SettingSync                    EnableBackupForWin8Apps : 1
System
WcmSvc
WindowsUpdate                  UpdateServiceUrlAlternate                    : http://localhost:8005
                               WUServer                                     : http://wsusserver.domainname.au:8530
                               WUStatusServer                               : http://wsus.domainname.au:8530
                               ElevateNonAdmins                             : 0
                               DoNotConnectToWindowsUpdateInternetLocations : 1
                               TargetGroupEnabled                           : 1
                               TargetGroup                                  : Auto Patch2
WorkplaceJoin                  (default) :
WSDAPI

After investigating this for a while, I found that the UpdateServiceUrlAlternate is a new setting introduced in the 2017 January update for Windows 10 1607 (and Server 2016, it would seem). For more details, see the Microsoft Documentation for UpdateServiceUrlAlternate.

We discovered that we had not been setting this with our current Group Policy, because we were using ADMX templates that were released before this was added. After updating our ADMX templates and setting that value to nothing, the updates download and install correctly again.

VMware User Environment Manager (UEM) Profile for Autodesk AutoCAD 2017 in VDI

In our Horizon View VDI environment we use UEM to manage some application’s user data. I used the Application Profiler included with UEM to create this profile for AutoCAD. One issue that we we have with AutoCAD is that it will reconfigure when launched by a new user. We tried to capture a default profile but the registry entries captured include lots of references to the specific user profile path for that user, which caused issues on launch. I have attached the INI file and icons to this post.

To prevent AutoCAD from crashing on launch, make sure to capture <LocalAppData>\Autodesk, which isn’t included by default when using the Application Profiler.

Application: Autodesk AutoCAD 2017

OS: Windows 7

INI Details:

# Flex config file generated with VMware User Environment Manager Application Profiler version 9.1

[IncludeRegistryTrees]
HKCU\Software\Autodesk
HKCU\SOFTWARE\FLEXlm License Manager

[IncludeFolderTrees]
<AppData>\Autodesk
# Added to prevent crash on launch
<LocalAppData>\Autodesk

[Metadata]
ProcessIfExists=
DirectFlexEnabled
DirectFlexPath=%ProgramFiles%\Autodesk\AutoCAD 2017\acad.exe
ProcessCriteria=
ProfilerChild=c:\program files\autodesk\autocad 2017\acwebbrowser\acwebbrowser.exe
ProfilerChild=c:\program files\autodesk\autocad 2017\admigrator.exe
ProfilerChild=c:\windows\microsoft.net\framework64\v4.0.30319\csc.exe
ProfilerChild=c:\windows\microsoft.net\framework64\v4.0.30319\cvtres.exe
ProfilerChild=c:\program files\autodesk\autocad 2017\dadispatcherservice.exe


[Immidio Flex]
This file was created using VMware UEM Management Console version 9.1.0.175.
Use only with VMware UEM.

Zipped INI File and Icon: Autodesk_AutoCAD_2017

Please feel free to comment with any issues or suggestions you had using AutoCAD with UEM in your environment.

Experiment: Using the Colemak Keyboard Layout For Two Weeks

Recently I have been investigating using better, more ergonomic computer equipment. To this end, several months ago I purchased an ergonomic keyboard, the Microsoft Natural Ergonomic Keyboard 4000. During my investigation of keyboards, however, I came across a lot of discussion about alternative keyboard layouts, and their various pros and cons, and have decided to try switching to the Colemak Keyboard layout.

About Me

I don’t have any issues with RSI, or pain or stiffness in my hands. I would like to keep it that way, and so I would like to use good ergonomic equipment and practices to keep my hands that way. I work in IT, and do a large amount of typing throughout the day, so even a small improvement to the quality of my typing can pay off for me.

Choosing Colemak

During my investigation on different keyboard layouts, I of course found a lot of information on Dvorak, another popular alternative layout. Certainly there are some significant benefits to Dvorak:

  1. It has more OS support (comes built-in on Windows)
  2. It’s more widely used, and therefore more studied.

So why choose Colemak?

  1. Most importantly for me, it keeps some of the keyboard shortcuts the same, like Ctrl-C, Ctrl-X and Ctrl-V. On Dvorak the common pattern Ctrl-C -> Ctrl-V are both two handed shortcuts. 🙁
  2. It has slightly less finger travel than Dvorak. For more details, see https://colemak.com/Ergonomic
  3. It keeps almost all the symbol keys in the same place, which is nice.

Day 1

The first day was so hard, and it went soooo slowly. Very frustrating, and by the end of the day I was getting only 12 WPM. I found I was constantly having to read off the image of the keyboard layout to type simple things.

Days 2 – 7

Once I got through the first day, I slowly improved over the next few days. I found that I was not having to look to remember the keys on the home row, and only check for keys above or below. However, even with the home row, I would get stuck with a mental block about once per sentence, trying to un-jumble the keys in my mind. This significantly slowed my typing, but as the week went on, the pauses would get shorter and less common.

Days 8 – 14

Once I was past the first week, I found I was no longer running into issues getting stuck, however my accuracy and speed were still lower than I had on QWERTY. However, as the week progresses I found my speed and accuracy picking up. I also started using the CapsLock backspace key, which is great.

Conclusion

So how fast am I typing now? I just tested my typing speed, and I’m getting 35 WPM. That’s not bad, but it’s not great. I have previously scored up to 50 WPM on QWERTY, although I haven’t tested my speed for a while. However, I plan to continue using Colemak, as I find it very comfortable to type on. We’ll see how I’m going after a couple of months of usage.

How to Opt-In and Detect to Microsoft Update for other Microsoft products using Powershell

Update 2018-03-25: Updated the script to make it more easily runnable from the command line (thanks Grant for the suggestion). I’ve also made the script available from on my Gitlab repo. To run the script from the command line, download it from the Gitlab repo, and then execute like this:

# CMD Prompt
powershell.exe -ExecutionPolicy Bypass -File C:\Configure-UpdateMSProducts.ps1 -RunType InstallService
# PowerShell Prompt
C:\Configure-UpdateMSProducts.ps1 -RunType InstallService

Update 2017-04-05: Thanks to some help from rog in the comments, I discovered there is a way to do this using group policy! 😀 To set this using group policy, go to Computer Configuration\Administrative Templates\Windows Components\Windows Update\ and configure the Configure Automatic Updates setting. In this setting there is a checkbox to set the Install updates for other Microsoft products setting. I will note, however, that this setting is not available in the local group policy editor for Windows 7, so I’m not sure if this setting would correctly apply to a Windows 7 machine. It’s definitely available on a Windows 10 1607 machine, though. Thanks for the help on this one, rog!

With Windows 10 out, we have been investigating how we can better deploy and manage Windows computers. Previously have deployed our images using an SCCM server, and then managed updates using WSUS integrated with SCCM, but Windows 10 brings a new update method, Windows Update for Business.

However, have you ever seen a checkbox with this label in your updates settings: Give me updates for other Microsoft products when I update Windows. How do you set this?

My first thought was to set this from group policy. Since this is how you set the Windows Update for Business settings, this would be the correct way to set the update method for other Microsoft products, right? So I have a look through the Windows Update, but can’t find the setting. I also do a little searching online, but all I can find is This Question on Microsoft’s forum. Here, JuliusPIV is asking the exact question I have.

So what’s the solution JuliusPIV found? This Microsoft page, Opt-In to Microsoft Update where Microsoft describes how to set enable it. Fixed, right?

There are two issues with this solution:

  1. It uses VBScript. I hate VB
  2. It doesn’t have any way to turn the setting back off again, or detect whether it is on or off

So I worked out how to do it in Powershell, and added a few extra options.

Solution:

Here’s how to turn it on

$ServiceManager = New-Object -ComObject "Microsoft.Update.ServiceManager"
$ServiceManager.ClientApplicationID = "My App"
$NewService = $ServiceManager.AddService2("7971f918-a847-4430-9279-4a52d1efe18d",7,"")

Here’s how to turn it off

$ServiceManager = New-Object -ComObject "Microsoft.Update.ServiceManager"
$ServiceManager.RemoveService("7971f918-a847-4430-9279-4a52d1efe18d")

Here’s a snippet of Powershell that will do whatever you want:

param(
    [String][ValidateSet('Detect','InstallService','RemoveService')]$RunType = "InstallService"
)

# Prepare a Windows Update service manager
$ServiceManager = New-Object -ComObject "Microsoft.Update.ServiceManager"

$ServiceID = "7971f918-a847-4430-9279-4a52d1efe18d"

# 
switch ($RunType)
{
    "Detect"
    {
        $found = $false
        foreach($service in $ServiceManager.Services)
        {
            if($service.ServiceID -eq $ServiceID)
            {
                $found = $true
            }
        }

        if($found)
        {
            "Found Service"
        }
    }
    "InstallService"
    {
        $ServiceManager.ClientApplicationID = "My App"
        try
        {
            $NewService = $ServiceManager.AddService2($ServiceID,7,"")
        }
        catch
        {
            Write-Warning "Failed to register service"
            Write-Warning $_.Exception.Message
            Exit 1
        }
        if($NewService.IsPendingRegistrationWithAU)
        {
            Write-Verbose "Needs to reboot"
            Exit 3010
        }
        else
        {
            Exit 0
        }
    }
    "RemoveService"
    {
        try
        {
            $ServiceManager.RemoveService($ServiceID)
        }
        catch
        {
            if($_.Exception.ErrorCode -eq -2145091564)
            {
                Write-Verbose "The service doesn't exist, so exit successfully"
                Exit 0
            }
            else
            {
                Write-Warning "Failed to remove service"
                Write-Warning $_.Exception.Message
                Exit 1
            }
        }
    }
    default
    {
        Write-Warning "No RunType set. Exiting"
        Exit 1
    }
}