More Windows build modules: Capabilities, Optional Features and OpenSSH Server

Posted by Craig Comstock
October 7, 2024

I promised more Build modules in my previous monthly Monday module blog post: package-method-winget.

And here they are: windows-capability and windows-optional-feature.

Inventory

Both of these modules use similar usage details to control whether to inventory and to promise the state for specific capabilities and optional features.

By default inventory is taken in the form of a classic array which ends up in the Mission Portal as a comma separated list:

OpenSSH.Server~~~~0.0.1.0:Installed, OpenSSH.Client~~~~0.0.1.0:Installed, etc.

To disable this inventory, define the class disable_windows_capability_inventory or disable_windows_optional_feature_inventory in the data namespace. The data namespace is the default if you use Host specific data or Group data. If you want to set these in augments you will need to specify the namespace explicitly like this:

"classes": {
  "data:disable_windows_capability_inventory": [ "windows" ]
}

Compliance report

Now that we have inventory we can make a compliance report based on this information. In my organization I expect OpenSSH server to be installed:

compliance check for openssh server installed on windows

The result of the report (after I include the policy example later in this post):

compliance report showing that all 1 windows host has openssh server installed

Bundles to promise state

  • windows_capability_installed(capability_name)
  • windows_capability_notpresent(capability_name)
  • windows_optional_feature_enabled(feature_name)
  • windows_optional_feature_disabled(feature_name)

And now let’s use these bundles in some example policy and utilize Host specific data to request the installs:

host specific data classes requesting install of openssh, steam and windows containers

Windows OpenSSH Installed

Having these two modules enables me to more easily install OpenSSH as a server on my Windows machines with the following policy:

bundle agent openssh_server
{
  methods:
    data:openssh_server_installed::
      "openssh_server_installed";
}

bundle agent openssh_server_installed
{
  methods:
    windows::
      "Add OpenSSH.Server Capability"
                usebundle => windows_capability_installed("OpenSSH.Server~~~~0.0.1.0"),
                classes => classes_generic("openssh");

  services:
    windows.openssh_ok::
      "sshd"
        service_policy => "start",
        service_method => winmethod;
}

body service_method winmethod
{
  service_type => "windows";
  service_autostart_policy => "boot_time";
}

This policy utilizes the built-in services promise type which in our Enterprise version supports the Windows platform.

Windows Containers with Docker Desktop Installed

I also wanted to get Windows Containers up and working. There are many ways to use containers on Windows: Docker Desktop, Docker Engine, containerd, BuildKit (uses containerd) and Stevedore to name several.

bundle agent windows_containers
{
  methods:
    data:windows_containers_installed::
      "windows_containers_installed";
}

bundle agent windows_containers_installed
{
  methods:
    windows::
      "windows_containers_dependencies";

  packages:
    windows::
      "Docker.DockerDesktop"
        package_method => winget,
        package_policy => "add";
}

bundle agent windows_containers_dependencies
{
  methods:
    windows::
      "enable-containers" usebundle => windows_optional_feature_enabled("containers");
      "enable-hyperv" usebundle => windows_optional_feature_enabled("Microsoft-Hyper-V");
}

Some manual steps :'(

This gets me part of the way there. I haven’t quite figured out how to get the Docker services started and switching to Windows Containers in an automated way just yet.

After some manual steps I can pull and run and exec in a Windows Container:

docker pull mcr.microsoft.com/windows/nanoserver:10.0.19042.1889-amd64
docker run -d --name test mcr.microsoft.com/windows/nanoserver:10.0.19042.1889-amd64 ping -t localhost
docker exec -it test cmd

And I get a Windows Cmd prompt!

Microsoft Windows [Version 10.0.19042.1889]
(c) Microsoft Corporation. All rights reserved.

C:\>

Note: I had to do some searching to find an image version that was compatible with my older version of Windows 10. That’s where the “10.0.19042.1889” came from. Searching the Microsoft Artifact Registry.

Next time

Maybe that policy will be my next blog: even-more-windows or automated-windows-docker-install.

Questions?

If you have questions or need help, reach out on the mailing list or GitHub discussions. If you have a support contract, feel free to open a ticket in our support system.