Windows Deployment Pipeline with MECM
A complete Windows 11 deployment pipeline built in Microsoft Endpoint Configuration Manager (MECM), from a bare domain controller to automated, PXE-based OS deployment. The build touched nearly every major MECM subsystem: site infrastructure and PKI, client deployment, application management, software updates, and operating system deployment.
Building the Foundation
Site infrastructure and PKI, from the ground up
DC01 runs as a deliberately all-in-one lab host: the Active Directory domain controller and MECM primary site server for the skybaerlabs.net domain (site code SBL), also hosting SQL Server and IIS.
A Management Point, four problems deep
The Management Point role failed installation outright (Critical, 0.00MB). Tracing it meant peeling back four separate issues: the Default Web Site had no SSL certificate bound, IIS’s default certificate request set only a Common Name instead of a Subject Alternative Name, the Certification Authority needed to move from Standalone to Enterprise mode but was blocked by a stale Kerberos token, and the AD System Management container was missing Full Control for the domain controller’s computer account.
One fix at a time, then a reboot
Resolving all four and rebooting brought the Management Point fully online, confirmed by its own status message.
The lesson that held for the whole build
MECM failures are rarely single-cause. DNS, certificates, permissions, and services each needed separate verification instead of assuming one fix would clear the whole chain, a pattern that repeated at every later stage of this build.
First Client and Application Deployment
Getting one Windows 11 VM fully managed
DESKTOP-TEST01, a domain-joined Windows 11 VM, became the first test client. The site was configured HTTPS-only with mandatory PKI client certificates, so client install depended on the certificate infrastructure being right before anything else would work.
Certificates before clients
Client installation required issuing a Workstation Authentication certificate template, granting Domain Computers autoenroll rights, and building a dedicated GPO for computer certificate autoenrollment, kept separate from Default Domain Policy on purpose.
A boundary group with corrupted data
“Failed to get DP locations” (error 0x87d00215) traced back to zero configured boundaries. Creating an IP subnet boundary (IP redacted) and a new boundary group fixed it, after discovering the site’s own default boundary group had corrupted WMI object data that survived both a service restart and a full server reboot. A fresh group was built rather than repairing the broken one.
The first working client
With boundaries and certificates in place, ccmsetup completed end to end and DESKTOP-TEST01 showed Client: Yes in the console, the lab’s first working MECM client.
Collections and a real application deployment
Three collections followed: a limiting collection by naming convention, a query-based collection, and a direct-membership deployment target. A full Notepad++ application deployment, script installer, silent switch, and file-system detection, completed and verified successfully on the client.
Software Updates
WSUS, backed by the site’s own SQL Server
The Software Update Point used a SQL-backed WSUS install, leaning on the SQL Server already running the MECM site database rather than the simpler Windows Internal Database option, closer to how a real enterprise deployment would be built.
A stale catalog, not a broken sync
The first synchronization attempt failed with “Request filter does not contain any known categories.” Native WSUS had never completed its own first-run wizard, so its product catalog was still the stale default bundled with the role, missing current Windows 11 categories entirely. Running WSUS’s own “Synchronize from Microsoft Update” pulled a live catalog: 223 stale categories replaced by 446 current ones.
A second, independent setting
MECM’s own Software Update Point Component Properties keeps its own Products/Classifications selection, separate from the native WSUS console, and the wrong Windows 11 variant had been selected there. Correcting both settings produced a real sync: 408 update items evaluated, 224 landed in the site database.
100% compliance
A manual Software Update Group built from the synced updates deployed to 100% compliance on DESKTOP-TEST01.
Recurring Infrastructure Lessons
What an all-in-one lab host keeps teaching
Running a domain controller, MECM primary site, SQL Server, IIS, a Certification Authority, and WSUS on one lab VM repeatedly exposed disk-sizing problems, with no single oversized culprit to blame.
C: drive, twice
C: dropped to roughly 3GB free twice: once blocking update-package content staging, once threatening to fill completely, despite WinSxS and SoftwareDistribution both sitting within normal range. The fix each time was the same: expand the VMware virtual disk while the VM was powered off, use diskpart to delete a small recovery partition blocking Disk Management’s Extend Volume option, then extend C:.
A host-level crisis too
The physical drive backing the VM files hit 0 bytes free at one point, requiring several lab VMs to be moved onto an external SSD.
The actual lesson
An all-in-one lab server needs deliberate storage headroom planned up front, not reactive expansion after each crisis.
Building the OSD/PXE Pipeline
From a base task sequence to a working PXE boot
Standing up OS deployment started with importing a Windows 11 OS image, building a base task sequence, and installing the WDS/PXE role on DC01.
Getting install.wim onto a real share
install.wim had to be copied out of the mounted ISO onto a real NTFS share before it could be imported, since CD-ROM volumes can’t be SMB-shared.
Real DHCP, and a silent checkbox
PXE boot required abandoning VMware’s built-in DHCP in favor of a real Windows DHCP server on DC01, plus manually setting DHCP option 60 (PXEClient) after the WDS console’s own “configure option 60” checkbox silently failed to apply it.
Three real dead ends before the actual fix
Even with a working PXE handshake, the task sequence never advertised: every boot attempt failed with PXE::MP_GetList / error 0x80070490. Ruling out the cause meant chasing down several issues that were each real and worth fixing on their own, but turned out not to be it: an unextended AD schema, a DC01 domain-membership resolution failure that had persisted for 12 days, and a broken local MECM client install on DC01 itself. Database queries confirmed the Management Point registration was valid, and Process Monitor traced the failing call to a direct SQL query from the PXE provider rather than an HTTP call to the MP. The actual fix was unrelated to any of that: the PXE-enabled distribution point’s Communication tab was set to require an imported client certificate, but the certificate field was empty, so every policy request failed silently with a non-issued-certificate error in MP_Policy.log. Issuing and importing a proper client-auth certificate from the lab CA finally got a PXE boot to pull the task sequence advertisement for the first time.
The Root-Cause Investigation
A 100% reproducible failure, traced to its source
With PXE and policy fixed, deployment reached the Apply Operating System step, then hit a new failure that reproduced on every single attempt, with no WinRE recovery screen ever appearing.
Windows Setup fails on every attempt, no exceptions
UnattendedJoin block in the generated unattend.xml, ruled out by switching the task sequence’s network settings from domain to workgroup and reproducing the identical failure anyway. Two genuine, separate infrastructure bugs were found and fixed along the way without resolving the core error: a WinHTTP certificate revocation check blocking live PXE-to-MP communication (fixed by disabling CRL checking at the site level), and a WDS TFTP Variable Window Extension bug blocking UEFI boot file transfer.setupact.log, setuperr.log) showed only stale content from the original capture-time sysprep run, nothing from an actual deployment attempt. Windows Event Logs told the same story more clearly: Setup.evtx, System.evtx, and most other channels sat at exactly 69,632 bytes, the default empty-file size, with timestamps from days before the failed attempt, proving zero logging activity from that deployment. The failure was happening before core OS logging infrastructure even initialized.Rebuilding the Base Image
A clean rebuild, with a safeguard added this time
With the image itself confirmed as the fault, the fix was a clean rebuild rather than further task-sequence troubleshooting.
A clean, workgroup-joined base
A fresh Windows 11 VM was built, patched, and configured as a local/workgroup machine, since domain join is handled later during deployment through unattend.xml rather than baked into the image.
A snapshot before the first sysprep run
Before running sysprep for the first time on the new instance, the VM was shut down and a VMware snapshot taken of that clean, pre-sysprep state, giving a safe rollback point for any future capture retry so a bad attempt no longer has to burn another generalize pass on a live instance.
Capturing outside ConfigMgr’s own tooling
Capture used an ADK-built, directly bootable WinPE ISO (via copype and MakeWinPEMedia) rather than ConfigMgr’s own Create Task Sequence Media Wizard, which has a confirmed bug: it invokes oscdimg.exe without the -bootdata parameter, producing non-bootable media.
A noticeably bigger image
Booting the new VM to that known-good WinPE environment and running dism /capture-image produced a clean Win11Base-v2.wim: 12.7GB, versus 7.7GB for the original.
Results and Lessons Learned
Confirmed twice, and what carries forward
The rebuilt image was imported as a new OS Image object, distributed to the distribution point, and swapped into the task sequence’s Apply Operating System Image step.
Confirmed, twice
Two separate PXE deployments, to DESKTOP-TEST02 and a freshly built DESKTOP-TEST03, both completed cleanly past the exact point that had failed 100% of the time before, confirming the sysprep rearm-exhaustion diagnosis.
Isolation tests beat guessing
A single reproducible failure can have a long list of plausible-looking causes. Isolation tests, like switching domain join to workgroup, settle the question faster than guessing from symptoms alone.
An empty log file is itself a finding
When application-level logs go quiet, it’s worth checking whether the OS’s own logging infrastructure ever initialized. A default-sized, empty event log file says something on its own.
Sysprep’s budget is finite
The generalize/rearm budget is easy to exhaust during iterative capture troubleshooting. Snapshotting the clean pre-sysprep state before the first run, every time, is now standard practice.
The tooling itself can be the bug
An MECM-generated deployment tool, ConfigMgr’s own Capture Media Wizard, turned out to be the actual bug. Building WinPE media directly from the ADK was both the workaround and, in hindsight, the more transparent method from the start.
PKI touches almost everything
HTTPS-only MECM sites push certificate requirements into nearly every subsystem. Client install, PXE policy retrieval, and Management Point communication all depend on certificates being correctly issued, bound, and imported.
