Dev Configuration

June 15, 2026 · View on GitHub

A WinGet Configuration (DSC) file that sets up a clean, lightweight, distraction-free developer workstation. The goal is a PC state that devs actually love using: no clutter, no noise, just the tools you need.

This mirrors the curated environment currently provided by Cloud PC, so developers get a consistent experience regardless of device.

The flow is a single DSC document (dev-config.winget) that handles everything end-to-end: elevation, the OS tweaks, the apps, the fonts, the shell prompt, and the WSL platform + Ubuntu install (including the reboot dance).

Author: Hamza Usmani.

Table of Contents


Goals

  • A PC devs actually want to use. Clean Explorer, dark theme, no pop-ups, no recommendations, no widgets. Just your code and your tools.
  • Cloud PC parity. Same tooling, OS settings, and policies as the current Cloud PC image.
  • One command. winget configure -f dev-config.winget --accept-configuration-agreements --disable-interactivity takes a fresh Windows machine to fully ready, including WSL + Ubuntu (with an auto-resume across the required reboot).
  • Idempotent. Safe to re-run on existing machines to apply updates or fix drift. Every resource has a testScript or DSC-native idempotency.

Prerequisites

  • Windows 11 (latest).
  • winget with the DSC v3 processor available (the file uses Microsoft.WinGet/Package, Microsoft.Windows/Registry, and Microsoft.DSC.Transitional/*).
  • Administrator rights — the ElevationCheck resource will auto-relaunch winget elevated via Start-Process -Verb RunAs if you started in an unelevated session, but you'll need to consent at the UAC prompt.
  • The Microsoft Visual C++ Redistributable when invoking winget from a non-elevated environment. Without it, winget configure fails with an internal error. See aka.ms/vcredist or install via winget (see the Usage callout below).
  • The repo on disk. winget configure reads a local file path, and the bootstrap is what installs Git, so on a fresh machine you'll either git clone (if Git is already installed) or download the repo as a ZIP from GitHub and extract it before running.
  • Hardware virtualization must be available to the OS before WSL can install. On bare metal, this means virtualization (VT-x / AMD-V) is enabled in BIOS/UEFI. Inside a VM, it means the host has exposed nested virtualization to the guest. See the Usage callout below.

Usage

Important

If winget is being invoked from a non-elevated environment, the Microsoft Visual C++ Redistributable (aka.ms/vcredist) must also be installed — without it winget configure fails with an internal error. Install it once with the command for your machine's architecture:

# x64:
winget install Microsoft.VCRedist.2015+.x64

# ARM64:
winget install Microsoft.VCRedist.2015+.arm64

Important

WSL needs hardware virtualization. If virtualization isn't available to the OS, the InstallUbuntu step fails with wsl --install ... failed with exit code -1.

  • On bare metal: enable virtualization (VT-x / AMD-V) in your BIOS/UEFI. The exact label varies by vendor — check your motherboard or laptop manufacturer's documentation if you can't find it. Reboot into firmware settings, toggle it on, save, and reboot back into Windows.

  • Inside a VM: the host must expose nested virtualization to the guest. For a Hyper-V host, run this from an elevated PowerShell session on the host (with the guest VM powered off):

    Set-VMProcessor -VMName <VM_NAME> -ExposeVirtualizationExtensions $true
    

    Other hypervisors have their own equivalent settings — check your hypervisor's documentation.

Get the files first (skip if you already have the repo locally):

# Git already installed:
git clone https://github.com/microsoft/WindowsDeveloperConfig.git
cd WindowsDeveloperConfig\windows-dev-config

# Otherwise, download and extract the ZIP:
Invoke-WebRequest -Uri https://github.com/microsoft/WindowsDeveloperConfig/archive/refs/heads/main.zip -OutFile WindowsDeveloperConfig.zip
Expand-Archive .\WindowsDeveloperConfig.zip -DestinationPath .
cd .\WindowsDeveloperConfig-main\windows-dev-config

Full setup (recommended):

winget configure -f dev-config.winget --accept-configuration-agreements --disable-interactivity

This is the canonical invocation documented in the header of dev-config.winget.

What to expect:

  1. The first phase applies all OS tweaks, installs apps, installs Cascadia Code/Mono Nerd Fonts, and configures Windows Terminal and the PowerShell profile.
  2. WSL platform components install; the DSC reboots the machine and registers a RunOnce resume.
  3. After login, winget configure resumes automatically and installs the default Ubuntu distro.
  4. Open Ubuntu from the Start menu to complete its first-launch setup (create a UNIX username and password).

The configuration is idempotent, so it is safe to re-run after reboot or at any later point.

What this configures

  • 14 apps via winget (PowerShell 7, Git, GitHub CLI, GitHub Copilot CLI, VS Code, .NET SDK 10, Python 3.14, UV, Node.js LTS, NVM for Windows, Coreutils for Windows, Windows Application CLI, plus optional Oh My Posh and PowerToys).
  • WSL + Ubuntu, installed via 3 transitional script resources that bracket a reboot (Phase 2/3/4 below).
  • ~24 registry settings for theme/OS, Explorer, Taskbar, Search, Start, Notifications, Edge, Sudo, and the Widget service.
  • Cascadia Code & Cascadia Mono Nerd Fonts downloaded from the microsoft/cascadia-code GitHub release and registered per-user.
  • 5 script resources beyond the WSL phases:
    • ElevationCheck — re-launches winget elevated if not already admin.
    • darkTheme — applies the built-in dark.theme to switch to dark mode.
    • InstallCascadiaCodeNerdFonts — downloads and installs the Nerd Font variants of Cascadia Code/Mono.
    • SetCascadiaNfAsDefault — sets Cascadia Mono NF as the default font face in Windows Terminal's settings.json.
    • ps7default — sets PowerShell 7 as Windows Terminal's default profile.
    • ohMyPoshProfileSet — adds oh-my-posh init pwsh | Invoke-Expression to $PROFILE and dot-sources it.

Configuration details

All resources are dscv3 ($schema: .../DSC/main/schemas/2023/08/config/document.json, metadata.winget.processor.identifier: dscv3). Every resource that touches HKLM or runs elevated tools depends on ElevationCheck.

Package resources use Microsoft.WinGet/Package with source: winget and useLatest: true (except Python.Python.3.14, Microsoft.dotnet.SDK.10, and OpenJS.NodeJS.LTS, which are pinned by id).

Phase resources (elevation + WSL)

NameTypeWhat it does
ElevationCheckMicrosoft.DSC.Transitional/WindowsPowerShellScripttestScript checks IsInRole(Administrator). If false, setScript re-invokes winget configure --file <this> --accept-configuration-agreements --disable-interactivity --wait via Start-Process -Verb RunAs, then throws so the unelevated session ends cleanly.
InstallWslComponentsMicrosoft.DSC.Transitional/WindowsPowerShellScripttestScript probes for the vmcompute service (presence ⇒ Virtual Machine Platform is active). setScript runs wsl --install --no-distribution.
RebootForVmpMicrosoft.DSC.Transitional/WindowsPowerShellScriptSame vmcompute test. setScript registers HKCU:\...\RunOnce\DSCConfigureResume with the same winget configure --file <this> --accept-configuration-agreements command, then Restart-Computer -Force and throws so DSC stops the current run.
InstallUbuntuMicrosoft.DSC.Transitional/WindowsPowerShellScripttestScript runs wsl --list --quiet and returns true if any distro is already registered. setScript runs wsl --install -d Ubuntu --no-launch.

All app resources that need WSL present depend on InstallUbuntu so the OS work happens before the reboot — but the WSL install is still part of the same winget configure invocation thanks to the RunOnce resume.

Apps

Resource namePackage idNotes
PowerShellMicrosoft.PowerShellDirect dependency on ElevationCheck.
GitGit.GitDepends on ElevationCheck + InstallUbuntu.
GitHubCLIGitHub.CliDepends on Git + InstallUbuntu.
GitHubCopilotGitHub.CopilotDepends on Git + InstallUbuntu.
VSCodeMicrosoft.VisualStudioCode
DotnetSdkMicrosoft.dotnet.SDK.10Pinned to v10.
PythonPython.Python.3.14Pinned to 3.14.
UVastral-sh.uv
NodeJSOpenJS.NodeJS.LTSPinned to the LTS line (currently Node 24 LTS).
nvmForNodeCoreyButler.NVMforWindowsNode version manager for Windows.
CoreutilsMicrosoft.CoreutilsMicrosoft-maintained Coreutils for Windows. Command integration is handled by the package itself after install.
OhMyPoshJanDeDobbeleer.OhMyPoshMarked Optional in the comments. Triggers ohMyPoshProfileSet.
winappCliMicrosoft.winappcliWindows Application CLI.
PowerToysMicrosoft.PowerToysMarked Optional. Followed by PowerToysAOT which disables AOT notifications via registry.

Theme and OS

Dark theme is applied via a RunCommandOnSet resource named darkTheme (not via registry):

ResourceTypeWhat it does
darkThemeMicrosoft.DSC.Transitional/RunCommandOnSetStart-Process on C:\Windows\Resources\Themes\dark.theme, sleeps 2 s, then stops SystemSettings so the Settings window doesn't linger. Depends on PowerShell.

The remaining theme/OS entries below are Microsoft.Windows/Registry.

ItemHive\Key\ValueValue
Sudo enabled (inline mode)HKLM\...\Sudo\EnabledDWord 3
Developer ModeHKLM\...\AppModelUnlock\AllowDevelopmentWithoutDevLicenseDWord 1
Long path supportHKLM\...\FileSystem\LongPathsEnabledDWord 1
Remote Desktop onHKLM\...\Terminal Server\fDenyTSConnectionsDWord 0

File Explorer

ItemHive\Key\ValueValue
Show file extensionsHKCU\...\Advanced\HideFileExtDWord 0
Show hidden filesHKCU\...\Advanced\HiddenDWord 1
Full path in titlebarHKCU\...\Advanced\FullPathAddressDWord 1
Open to This PCHKCU\...\Advanced\LaunchToDWord 1
Frequent folders offHKCU\...\Advanced\ShowFrequentDWord 0
Frequent files offHKCU\...\Explorer\ShowRecentDWord 0
Recommended/cloud files offHKCU\...\Explorer\ShowCloudFilesInQuickAccessDWord 0
Git integration in ExplorerHKCU\...\Advanced\NavPaneShowVersionControlDWord 1
Tips/sync-provider notifications offHKCU\...\Advanced\ShowSyncProviderNotificationsDWord 0

Taskbar

ItemHive\Key\ValueValue
Widgets button hiddenHKCU\...\Advanced\TaskbarDaDWord 0
Bluetooth notification icon offHKCU\Control Panel\Bluetooth\Notification Area IconDWord 0
End Task on right-clickHKCU\...\Advanced\TaskbarEndTaskDWord 1

Start, Search, Notifications

ItemHive\Key\ValueValue
Web search suggestions offHKCU\...\Policies\Explorer\DisableSearchBoxSuggestionsDWord 1
Search highlights offHKCU\...\SearchSettings\IsDynamicSearchBoxEnabledDWord 0
Start menu recommendations offHKCU\...\Advanced\Start_LayoutDWord 1
Toast notifications off (Do Not Disturb)HKCU\...\Notifications\Settings\NOC_GLOBAL_SETTING_TOASTS_ENABLEDDWord 0

Services and features

ItemHive\Key\ValueValue
Widget service off (HKLM policy)HKLM\SOFTWARE\Policies\Microsoft\Dsh\AllowNewsAndInterestsDWord 0
PowerToys AOT notifications offHKCU\...\Notifications\Settings\PowerToys\EnabledDWord 0

Edge

HKLM policies, applied via Microsoft.Windows/Registry:

ItemHive\Key\ValueValue
New tab blankHKLM\SOFTWARE\Policies\Microsoft\Edge\NewTabPageLocationString about:blank
First-run experience offHKLM\SOFTWARE\Policies\Microsoft\Edge\HideFirstRunExperienceDWord 1

Fonts

ResourceTypeWhat it does
InstallCascadiaCodeNerdFontsMicrosoft.DSC.Transitional/RunCommandOnSetDownloads CascadiaCode-2407.24.zip from microsoft/cascadia-code GitHub Releases, extracts CascadiaCodeNF.ttf and CascadiaMonoNF.ttf to %LOCALAPPDATA%\Microsoft\Windows\Fonts, and registers each under HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts. Per-user install — no admin required for this step. Depends on PowerShell.

Windows Terminal

ResourceTypeWhat it does
SetCascadiaNfAsDefaultMicrosoft.DSC.Transitional/RunCommandOnSetLocates Windows Terminal's settings.json (Store or unpackaged install), backs it up to settings.json.bak, and sets profiles.defaults.font.face = "Cascadia Mono NF". Depends on InstallCascadiaCodeNerdFonts.
ps7defaultMicrosoft.DSC.Transitional/RunCommandOnSetInvokes pwsh.exe -NoProfile -NoLogo -Command ... which reads %LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json, finds the PowerShell 7 profile, and sets it as defaultProfile. Depends on PowerShell.

PowerShell profile

ResourceTypeWhat it does
ohMyPoshProfileSetMicrosoft.DSC.Transitional/RunCommandOnSetCreates $PROFILE if missing and appends `oh-my-posh init pwsh

Customization

  • Pick and choose packages. Comment out any Microsoft.WinGet/Package block to skip that install — most have no dependsOn chain beyond InstallUbuntu (exceptions: GitHubCLI and GitHubCopilot depend on Git; PowerToysAOT depends on PowerToys; ohMyPoshProfileSet depends on OhMyPosh).
  • Pin or unpin versions. Switch id: Python.Python.3.14 (pinned) to id: Python.Python.3 if you want to drift forward, or switch OpenJS.NodeJS.LTS to OpenJS.NodeJS for current. Vice versa for the unpinned packages.
  • Toggle registry values. Most settings are DWord: 0 or DWord: 1; flip the value to invert the behavior.
  • Re-enable commented-out tweaks. HideDesktopIcons ships commented out (it over-fires on some user setups). Uncomment to enable.
  • Change the WSL distro. Edit the wsl --install -d Ubuntu --no-launch line inside the InstallUbuntu resource.
  • Change the terminal font. Edit $fontFace = 'Cascadia Mono NF' inside SetCascadiaNfAsDefault, or change the $WantedFonts array in InstallCascadiaCodeNerdFonts to install a different Cascadia variant.
  • Skip the dark theme step. Comment out the darkTheme resource if you prefer light mode (or want to set it manually).

Design decisions

DecisionRationale
Single dscv3 document, no modulesEasier to reason about and easier to re-run. The whole flow is one winget configure call.
Microsoft.Windows/Registry everywhere instead of Microsoft.Windows.Developer/* or Microsoft.Windows.Settings/WindowsSettingsDirect registry control is reliable across Windows 11 builds and avoids dependencies on legacy resource modules.
Microsoft.DSC.Transitional/WindowsPowerShellScript (not PSDscResources/Script)The dscv3 transitional resource is the supported equivalent under the new processor.
Self-relaunch elevated from ElevationCheckA user can double-click into an unelevated shell and the DSC will UAC-prompt itself rather than failing.
Reboot + RunOnce inside the DSCThe DSC owns the reboot and the resume, so the user only invokes winget configure once. The throw after Restart-Computer -Force is required because Restart-Computer returns immediately after signalling shutdown; without the throw DSC would treat the resource as succeeded and continue.
useLatest: true on most packagesCloud PC parity tracks "current" tools. Pinned ids (Python.Python.3.14, Microsoft.dotnet.SDK.10, OpenJS.NodeJS.LTS) are used where a major-version line matters.
Dark theme via dark.theme file (not registry)Applying the shipped .theme file flips both AppsUseLightTheme and SystemUsesLightTheme and applies the matching color scheme/cursors atomically, which the broadcast-message dance you'd otherwise need from a registry-only approach often misses.
Per-user font installAvoids requiring admin for the font step and keeps the font registration under HKCU, which is what modern Windows + Terminal expect.
RunCommandOnSet to mutate settings.jsonWindows Terminal's settings are JSON-based and not registry-mapped; a small pwsh fragment is the cleanest way.

Known caveats

AreaCaveat
acceptAgreements not on packagesNone of the Microsoft.WinGet/Package resources set acceptAgreements: true. The header comment compensates by passing --accept-configuration-agreements on the command line.
WSL rebootRebootForVmp will hard-reboot the machine via Restart-Computer -Force. Save your work before running. The RunOnce key resumes the config on next login.
Ubuntu first-launchAfter InstallUbuntu, you still need to open Ubuntu from the Start menu once to create a UNIX user. Nothing inside the distro is configured by this flow.
useLatest: trueEach run grabs the latest available version. Builds may differ between machines applying the config on different days.
HKLM registry keysSudo, the Widget service policy, Edge policies, Remote Desktop, Long Paths, and Developer Mode all live in HKLM. The ElevationCheck gate guarantees the run is elevated; without it these would silently fail.
PowerToys AOT pathHKCU\...\Notifications\Settings\PowerToys\Enabled targets a specific registry path that may change across PowerToys versions.
Idempotency of WSL phasesInstallWslComponents and RebootForVmp both test for vmcompute. Re-running after the reboot is a no-op for those resources. InstallUbuntu queries wsl --list --quiet, so it skips once any distro is registered.
Pinned font releaseInstallCascadiaCodeNerdFonts hard-codes Cascadia Code release 2407.24 from microsoft/cascadia-code. Bump $Version to pick up newer releases.
Windows Terminal settings overwriteSetCascadiaNfAsDefault and ps7default rewrite settings.json via ConvertTo-Json. SetCascadiaNfAsDefault writes a settings.json.bak first; ps7default does not. JSON comments will not survive the round-trip.
ohMyPoshProfileSet runs . $PROFILEDot-sourcing the profile inside pwsh -NoProfile can surface errors from the user's existing profile during DSC apply.
darkTheme opens Settings brieflyApplying dark.theme pops the Settings app open; the script kills it after 2 seconds. On slow machines the window may flash visibly.
Currently commented outThe HideDesktopIcons block lives in the file but is commented out. Uncomment to hide desktop icons.