guest@6admin.io:~$

Windows 11 for build machines: the wrong tool

Bare-metal build machines, automated, sitting in a server room with no screen or keyboard and on them Windows 11 client edition. On paper it works, over time it costs and this post is the detail of what it costs, because each friction taken in isolation looks surmountable and it is their sum, repeated at every feature update, that ends up being the real price. The conclusion fits in one sentence: for a build machine that needs a graphical session, Windows Server with Desktop Experience does exactly the same job with none of this friction and Windows 11 should stay on the workstations where a human sits in front of the machine, the use case Microsoft designed it for.

Provisioning fights the OS

Windows 11 downloads and installs updates during and after OOBE, unsolicited reboots included, which collides directly with post-install automation, a playbook running and a machine vanishing mid-way. Server editions defer updates by default and wait for a policy. On top of that come the hardware checks, TPM 2.0, Secure Boot and CPU generation, that Windows 11 enforces and a PXE environment does not expose, hence the bypass registry keys to inject at install time, each one a failure point and a test surface more per hardware generation. And the consumer OOBE, Microsoft accounts, Copilot, telemetry, privacy screens, to suppress one by one in the unattend, which swells with Windows-11-specific conditionals that a mere feature update, 24H2, 25H2, can break without warning by adding a screen. Server has a minimal, automation-friendly OOBE and none of these hardware requirements.

SSH, Ansible and a transport debt

This is where it gets thorny and the underlying cause has to be named: Ansible’s native and recommended transport for Windows is WinRM, not SSH. A group IT policy forbade WinRM in the infrastructure, which led to adopting SSH as the sole transport for Windows automation and all the debt that follows comes from using SSH where WinRM was designed to be (the SSH transport’s session limits are detailed in the hardened transport article ).

On Windows 11 specifically, the PowerShell subsystem emits CLIXML error objects on stderr more aggressively than Server editions, which breaks Ansible’s JSON parsing on a classic No start of json char found, a long-standing bug observed for real on 11 hosts while the same playbook passes without complaint on Server 2022. SSH connection multiplexing, standard practice for Ansible performance, is unstable with Windows 11’s OpenSSH, with intermittent UNREACHABLE, so it has to be disabled and a handshake per task accepted. And long-running tasks, win_updates first among them, see Windows 11’s OpenSSH cut the session mid-way, Connection reset by peer, which forces wrapping every update in an async/poll, splitting the reboot into a conditional task because async is incompatible with reboot: true and hardening the keepalive, three times more YAML than a simple win_updates: reboot: true that works reliably on Server. Add a verbosity-dependent bug where a task fails at normal level and passes at -vvvv and a documented history of Microsoft breaking OpenSSH from one feature update to the next, 23H2 and 24H2, where Server’s OpenSSH is a far more resilient system component. A migration to WinRM is now planned and it will make this entire problem space vanish at once, but it is itself an effort that would never have been necessary had WinRM been permitted from the outset.

RDP, sessions and headless GPU

A build machine needs an open graphical session, build tools, render pipelines, GPU workloads and it is in a server room with no screen. Windows Server natively supports multiple concurrent RDP sessions, so a build session and an admin session coexist. Windows 11 allows only one interactive session at a time, a licensing restriction and not a technical one with no supported workaround, which means an admin connecting for maintenance disconnects the running build session, at the risk of corrupting a shader compile or an asset cook and monitoring the build user’s session disrupts it. 24H2 further introduced several documented RDP regressions, a frozen screen on reconnect whose only remedy is a full reboot, broken UDP transport to work around by forcing TCP, faulty network detection to disable by GPO, each to be re-validated after every cumulative update. And in a server room with no screen, Windows 11 can show GPU driver trouble when no monitor is detected, hence the dummy HDMI plugs or headless profiles, where Server treats headless and GPU partitioning as supported configurations.

A note on operations in passing, because it holds for any server-room fleet: an IP KVM for the console, BIOS, blue screens, pre-boot diagnostics and a manageable PDU for per-outlet power-cycling, remove the bulk of physical interventions, Windows 11 or not.

The rest and the recurring cost

Windows 11 ships with its consumer bloatware, Teams, Copilot, Widgets, Store, which consumes and adds non-deterministic noise on machines where performance must be predictable and whose removal has to be re-validated after each feature update because Microsoft reintroduces what you removed. The feature updates, precisely, are annual and each is in practice a full OS upgrade that can break the templates, OpenSSH, RDP behaviour, drivers and there is no Windows 11 LTSC for general use, the IoT Enterprise LTSC being licensed for fixed-function devices only. Server, by contrast, offers long-support LTSC releases, no forced feature update, security fixes only. All of this is recurring engineering time that does not exist on the Server pipeline, already validated and operational: dedicated SSH group_vars, the async/poll + win_reboot pattern on every win_updates, unattend conditionals per feature update, GPO workarounds re-validated per cumulative update, de-bloatware scripts re-validated per feature update, a full annual QA cycle.

A desktop for no one

Each friction in this post is surmountable taken alone and that is the trap, because you surmount them one by one without seeing the sum, until the recurring cost becomes the norm. Windows Server with Desktop Experience gives the same shell, the same desktop, the same GPU acceleration, native multi-session RDP, a stable provisioning already in production, LTSC support, a bloatware-free OS and a stable OpenSSH, with none of these workarounds. The choice is not ideological, it is economic: you pay for Windows 11 in recurring engineering time and Server takes that time back. Windows 11 is made for a human in front of their machine and a headless build machine in a server room is not that use case.