Control the Windows Update service on multiple servers with a single minimalistic GUI client.
Control the Windows Update service on multiple servers with a single minimalistic GUI client.
Years ago, I had to manage a lot of Windows servers. There were patch evenings on a regular basis. In spite of the availability of WSUS and group policies, it was complicated to automate the patch process for a multitude of reasons. For example:
...and so on.
I was tired of the many manual RDP logins to coordinate the dependencies between the "manual intervention" servers.
There were only expensive "Windows Update" management applications on the market, with a lot of features I was not interested in. So I wrote my own small solution.
The project consists of two parts, an agent that needs to be installed on the Windows servers you want to manage, and a WPF client application.
The client can connect to agents and send commands like "search", "select update", "download", "install" and "reboot". The agent will push progress and state changes back to all connected clients.
The agent uses the Windows Update Agent API provided by Microsoft to transmit the commands from the clients to Windows Update. The agent itself does not do any search, download or installation of updates. This is all handled by the Windows Update service. The advantage is, that there is no custom update routine which can damage the system. That also means that configurations for WSUS will be respected.
Regardless of changes in Microsoft's update policy with newer OS versions, the Windows Update Agent API seems to have been stable for the last couple of years.
When the agent starts, it creates an update session to communicate with Windows Update. Operations in one update session are isolated from operations in other update sessions. For example, the Windows Update menu of the control panel uses it's own update session. Thereby, the activity of the agent is not shown in the Windows Update menu of the control panel. Nevertheless, Windows Update handles concurrent sessions correctly. Only one session at time is able to install updates. The agent reacts to such situations and reports that the requested operation is not possible due activity of other sessions. Updates, that are downloaded by other sessions, will not be downloaded again, all sessions use the same "update storage".
The Windows Update Agent API protects the agent from doing invalid actions, but also needs to be interfaced correctly. The agent manages an internal state machine to implement a valid patch flow. The client can use commands to advance through the states. Invalid transitions will be rejected. Some transitions occur automatically based on events in the Windows Update session.
Some transitions have preconditions, which are not shown in the diagram. E.g. to enter the "Downloading" state, there must be updates available, which are not already downloaded. The client knows these rules and disables inappropriate commands for the user.
The solution is designed to be used in a classic Windows Active Directory environment.
The communication between client and agent is realized with WCF over the tcp protocol. By default the communication is encrypted and signed at transportation level by using TLS.
To authenticate connections between the client and the agents, Kerberos or NTLM authentication will be performed, depending on the host configuration. The client will be authenticated with the Windows user context, in which it is running. The agent rejects any user that does not have local administrator privileges on its host. This means, to manage a group of servers, you need to run the client, using an Active Directory user that has these permissions on all managed hosts. This authorisation behavior is currently hardcoded.
When UAC is turned on, you may need to start the client with elevated permissions to gain the administrator privileges.
The solution is designed to be used in a classic Windows Active Directory environment.
The agent is designed as long running process with a small footprint on the host system. While the agent itself does not consume a lot of CPU cycles, remember that Windows Update can and will use a considerable amount of ressources, when an action is requested.
Unpack the zip and copy the content to the desired location. Before you start the agent or install it as service, you may want to configure the agent. The agent is operable with the default settings. For testing purposes, you can start the agent as console application by simply executing WcfWuRemoteService.exe
.
There are only a few settings, that makes sense to be changed:
XML Attribute | Description |
---|---|
autoAcceptEulas | Some updates requires EULA acceptance. When enabled, the EULAs will be accepted automatically before download or installation. Manual acceptance is possible via the client. |
autoSelectUpdates | When enabled, important updates will automatically be selected for installation. You are still able to add/remove the selection of updates with the client. |
createFirewallRule | When enabled, the agent tries to register itself in the windows firewall and opens the configured port for its binary. On shutdown, the agent tries to remove this rule. |
baseAddress | Configures the binding. You may want change the port or binding IP. |
<configuration>
<wuapicontroller autoSelectUpdates="true" autoAcceptEulas="false" />
<wuservice createFirewallRule="false" />
<system.serviceModel>
<services>
<service name="WcfWuRemoteService.WuRemoteService">
<host>
<baseAddresses>
<add baseAddress="net.tcp://0.0.0.0:8523/WuRemoteService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
To configure the log, visit Apache log4net™ Manual - Configuration. You should adjust the log file path and log level to your needs.
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
</appender>
<root>
<level value="Info" />
</root>
</log4net>
Here is a PowerShell example to register the agent as Windows service. The service will be executed with LocalSystem
privileges.
PS> New-Service -Name 'WuRemoteService' -DisplayName "Windows Update Remote Service" -BinaryPathName '<Path to extracted WcfWuRemoteService.exe>' -StartupType Automatic
PS> Start-Service 'WuRemoteService'
To uninstall, execute sc.exe delete WuRemoteService
and remove the files.
The agent was only tested with LocalSystem
privileges. I never tried out the least privilege requirements. If you want to try, these are my suggestions to start with:
createFirewallRule
to false
. This avoids the usage of COM interfaces FwCplLua
and NetFwTypeLib
to configure the Windows firewall.WUApiLib
to interact with Windows Update. Maybe this can be done with DCOMCNFG.Please send me your "least privileges solution" if you come up with one. I will update this section with your results.
Unpack the zip and copy the content to the desired location, then execute WcfWuRemoteClient.exe
. When you get "access denied" messages while connecting to agents, despite local administrator privileges on the target hosts, start the client with elevated privileges.
WcfWuRemoteClient.exe
and WcfWuRemoteService.exe
. You need local administrator privileges and you may need to start the proccess with right click and "Run as administrator" for full elevated privileges.net.tcp://localhost:8523/WuRemoteService
should be fine, so just click on "Add".You should now see something like that:
Depending on the search result, you can now take other actions.
I upgraded the origin solution built with Visual Studio 2015 to be compatible with Visual Studio 2019. I also migrated all contained projects to the new SDK format. You need to install "Windows Communication Foundation" and ".NET desktop development workload" with Visual Studio Installer. The solution uses MS Test as unit test framework.
If you compile with DEBUG configuration, the agent uses WuApiMocks.WuApiSimulator
, which mimics basic behavior of WindowsUpdateApiController.WuApiController
. No changes to your OS are made, when you install the simulated updates. This allows independent development of the WCF (communication) and WPF (client) stuff. The DEBUG configuration also disables the "local administrator" autorisation check. So there is no need to run Visual Studio with local administrator privileges, while debugging the applications.
Developing the WindowsUpdateApiController.WuApiController
can be very challenging, when you need some integration tests with the Windows Update Agent API. How to tell windows to fail an installation to see how WuApiController
reacts?
For some integration tests, I used a VM to quickly reset to a state without patches. Limiting the disk space on the system drive while Windows Update expands/installs updates, is one way to provoke a failure. With WSUS you can better control, which updates are presented to Windows Update.
This is the first public release.
In 2015, I investigated the WUApiLib
and wrote a prototype. The biggest part of the solution was written in 2016 as a personal coding project. I added some small enhancements in 2017 to fit my use cases better. In 2018, I removed the GUI-installer/MSI part from the solution, because the native support for such project types was removed from Visual Studio. For the public release in 2020, I added license informations. I also ensured that Visual Studio 2019 is able to build the project and upgraded to the new SDK format.
Developed by Elia Seikritt – [email protected], https://github.com/EliaSaSe
The preferred method of communication is via GitHub.
Distributed under the GNU Lesser General Public License. See COPYING
and COPYING.LESSER
for more information.
This project uses the following libraries:
The project is not under active development, but I'm still using the software for some edge cases. I try to keep the project compatible with current Visual Studio versions to be able to compile binaries as long as I'm using this software.
Currently there is no contribution guideline. If you are interested in contributing, raise an issue to let me know. I will then add such a guideline.