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.
- Goals
- Prerequisites
- Usage
- What this configures
- Configuration details
- Customization
- Design decisions
- Known caveats
- 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-interactivitytakes 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
testScriptor DSC-native idempotency.
- Windows 11 (latest).
wingetwith the DSC v3 processor available (the file usesMicrosoft.WinGet/Package,Microsoft.Windows/Registry, andMicrosoft.DSC.Transitional/*).- Administrator rights — the
ElevationCheckresource will auto-relaunch winget elevated viaStart-Process -Verb RunAsif you started in an unelevated session, but you'll need to consent at the UAC prompt.
Full setup (recommended):
winget configure -f dev-config.winget --accept-configuration-agreements --disable-interactivityThis is the canonical invocation documented in the header of dev-config.winget.
What to expect:
- The first phase applies all OS tweaks, installs apps, installs Cascadia Code/Mono Nerd Fonts, and configures Windows Terminal and the PowerShell profile.
- WSL platform components install; the DSC reboots the machine and registers a
RunOnceresume. - After login, winget configure resumes automatically and installs the default Ubuntu distro.
- 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.
- 13 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, 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-codeGitHub 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-indark.themeto switch to dark mode.InstallCascadiaCodeNerdFonts— downloads and installs the Nerd Font variants of Cascadia Code/Mono.SetCascadiaNfAsDefault— setsCascadia Mono NFas the default font face in Windows Terminal'ssettings.json.ps7default— sets PowerShell 7 as Windows Terminal's default profile.ohMyPoshProfileSet— addsoh-my-posh init pwsh | Invoke-Expressionto$PROFILEand dot-sources it.
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).
| Name | Type | What it does |
|---|---|---|
ElevationCheck |
Microsoft.DSC.Transitional/WindowsPowerShellScript |
testScript 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. |
InstallWslComponents |
Microsoft.DSC.Transitional/WindowsPowerShellScript |
testScript probes for the vmcompute service (presence ⇒ Virtual Machine Platform is active). setScript runs wsl --install --no-distribution. |
RebootForVmp |
Microsoft.DSC.Transitional/WindowsPowerShellScript |
Same 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. |
InstallUbuntu |
Microsoft.DSC.Transitional/WindowsPowerShellScript |
testScript checks for any subkey under HKCU:\...\Lxss. 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.
| Resource name | Package id | Notes |
|---|---|---|
PowerShell |
Microsoft.PowerShell |
Direct dependency on ElevationCheck. |
Git |
Git.Git |
Depends on ElevationCheck + InstallUbuntu. |
GitHubCLI |
GitHub.Cli |
Depends on Git + InstallUbuntu. |
GitHubCopilot |
GitHub.Copilot |
Depends on Git + InstallUbuntu. |
VSCode |
Microsoft.VisualStudioCode |
|
DotnetSdk |
Microsoft.dotnet.SDK.10 |
Pinned to v10. |
Python |
Python.Python.3.14 |
Pinned to 3.14. |
UV |
astral-sh.uv |
|
NodeJS |
OpenJS.NodeJS.LTS |
Pinned to the LTS line (currently Node 24 LTS). |
nvmForNode |
CoreyButler.NVMforWindows |
Node version manager for Windows. |
OhMyPosh |
JanDeDobbeleer.OhMyPosh |
Marked Optional in the comments. Triggers ohMyPoshProfileSet. |
winappCli |
Microsoft.winappcli |
Windows Application CLI. |
PowerToys |
Microsoft.PowerToys |
Marked Optional. Followed by PowerToysAOT which disables AOT notifications via registry. |
Dark theme is applied via a RunCommandOnSet resource named darkTheme (not via registry):
| Resource | Type | What it does |
|---|---|---|
darkTheme |
Microsoft.DSC.Transitional/RunCommandOnSet |
Start-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.
| Item | Hive\Key\Value | Value |
|---|---|---|
| Sudo enabled (inline mode) | HKLM\...\Sudo\Enabled |
DWord 3 |
| Developer Mode | HKLM\...\AppModelUnlock\AllowDevelopmentWithoutDevLicense |
DWord 1 |
| Long path support | HKLM\...\FileSystem\LongPathsEnabled |
DWord 1 |
| Remote Desktop on | HKLM\...\Terminal Server\fDenyTSConnections |
DWord 0 |
| Item | Hive\Key\Value | Value |
|---|---|---|
| Show file extensions | HKCU\...\Advanced\HideFileExt |
DWord 0 |
| Show hidden files | HKCU\...\Advanced\Hidden |
DWord 1 |
| Full path in titlebar | HKCU\...\Advanced\FullPathAddress |
DWord 1 |
| Open to This PC | HKCU\...\Advanced\LaunchTo |
DWord 1 |
| Frequent folders off | HKCU\...\Advanced\ShowFrequent |
DWord 0 |
| Frequent files off | HKCU\...\Explorer\ShowRecent |
DWord 0 |
| Recommended/cloud files off | HKCU\...\Explorer\ShowCloudFilesInQuickAccess |
DWord 0 |
| Git integration in Explorer | HKCU\...\Advanced\NavPaneShowVersionControl |
DWord 1 |
| Tips/sync-provider notifications off | HKCU\...\Advanced\ShowSyncProviderNotifications |
DWord 0 |
| Item | Hive\Key\Value | Value |
|---|---|---|
| Widgets button hidden | HKCU\...\Advanced\TaskbarDa |
DWord 0 |
| Bluetooth notification icon off | HKCU\Control Panel\Bluetooth\Notification Area Icon |
DWord 0 |
| End Task on right-click | HKCU\...\Advanced\TaskbarEndTask |
DWord 1 |
| Item | Hive\Key\Value | Value |
|---|---|---|
| Web search suggestions off | HKCU\...\Policies\Explorer\DisableSearchBoxSuggestions |
DWord 1 |
| Search highlights off | HKCU\...\SearchSettings\IsDynamicSearchBoxEnabled |
DWord 0 |
| Start menu recommendations off | HKCU\...\Advanced\Start_Layout |
DWord 1 |
| Toast notifications off (Do Not Disturb) | HKCU\...\Notifications\Settings\NOC_GLOBAL_SETTING_TOASTS_ENABLED |
DWord 0 |
| Item | Hive\Key\Value | Value |
|---|---|---|
| Widget service off (HKLM policy) | HKLM\SOFTWARE\Policies\Microsoft\Dsh\AllowNewsAndInterests |
DWord 0 |
| PowerToys AOT notifications off | HKCU\...\Notifications\Settings\PowerToys\Enabled |
DWord 0 |
HKLM policies, applied via Microsoft.Windows/Registry:
| Item | Hive\Key\Value | Value |
|---|---|---|
| New tab blank | HKLM\SOFTWARE\Policies\Microsoft\Edge\NewTabPageLocation |
String about:blank |
| First-run experience off | HKLM\SOFTWARE\Policies\Microsoft\Edge\HideFirstRunExperience |
DWord 1 |
| Resource | Type | What it does |
|---|---|---|
InstallCascadiaCodeNerdFonts |
Microsoft.DSC.Transitional/RunCommandOnSet |
Downloads 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. |
| Resource | Type | What it does |
|---|---|---|
SetCascadiaNfAsDefault |
Microsoft.DSC.Transitional/RunCommandOnSet |
Locates 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. |
ps7default |
Microsoft.DSC.Transitional/RunCommandOnSet |
Invokes 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. |
| Resource | Type | What it does |
|---|---|---|
ohMyPoshProfileSet |
Microsoft.DSC.Transitional/RunCommandOnSet |
Creates $PROFILE if missing and appends `oh-my-posh init pwsh |
- Pick and choose packages. Comment out any
Microsoft.WinGet/Packageblock to skip that install — most have nodependsOnchain beyondInstallUbuntu(exceptions:GitHubCLIandGitHubCopilotdepend onGit;PowerToysAOTdepends onPowerToys;ohMyPoshProfileSetdepends onOhMyPosh). - Pin or unpin versions. Switch
id: Python.Python.3.14(pinned) toid: Python.Python.3if you want to drift forward, or switchOpenJS.NodeJS.LTStoOpenJS.NodeJSfor current. Vice versa for the unpinned packages. - Toggle registry values. Most settings are
DWord: 0orDWord: 1; flip the value to invert the behavior. - Re-enable commented-out tweaks.
HideDesktopIconsships commented out (it over-fires on some user setups). Uncomment to enable. - Change the WSL distro. Edit the
wsl --install -d Ubuntu --no-launchline inside theInstallUbunturesource. - Change the terminal font. Edit
$fontFace = 'Cascadia Mono NF'insideSetCascadiaNfAsDefault, or change the$WantedFontsarray inInstallCascadiaCodeNerdFontsto install a different Cascadia variant. - Skip the dark theme step. Comment out the
darkThemeresource if you prefer light mode (or want to set it manually).
| Decision | Rationale |
|---|---|
| Single dscv3 document, no modules | Easier 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/WindowsSettings |
Direct 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 ElevationCheck |
A user can double-click into an unelevated shell and the DSC will UAC-prompt itself rather than failing. |
| Reboot + RunOnce inside the DSC | The 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 packages |
Cloud 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 install | Avoids requiring admin for the font step and keeps the font registration under HKCU, which is what modern Windows + Terminal expect. |
RunCommandOnSet to mutate settings.json |
Windows Terminal's settings are JSON-based and not registry-mapped; a small pwsh fragment is the cleanest way. |
| Area | Caveat |
|---|---|
acceptAgreements not on packages |
None of the Microsoft.WinGet/Package resources set acceptAgreements: true. The header comment compensates by passing --accept-configuration-agreements on the command line. |
| WSL reboot | RebootForVmp 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-launch | After 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: true |
Each run grabs the latest available version. Builds may differ between machines applying the config on different days. |
| HKLM registry keys | Sudo, 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 path | HKCU\...\Notifications\Settings\PowerToys\Enabled targets a specific registry path that may change across PowerToys versions. |
| Idempotency of WSL phases | InstallWslComponents and RebootForVmp both test for vmcompute. Re-running after the reboot is a no-op for those resources. InstallUbuntu tests for any Lxss subkey, so it skips once any distro is registered. |
| Pinned font release | InstallCascadiaCodeNerdFonts hard-codes Cascadia Code release 2407.24 from microsoft/cascadia-code. Bump $Version to pick up newer releases. |
| Windows Terminal settings overwrite | SetCascadiaNfAsDefault 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 . $PROFILE |
Dot-sourcing the profile inside pwsh -NoProfile can surface errors from the user's existing profile during DSC apply. |
darkTheme opens Settings briefly |
Applying dark.theme pops the Settings app open; the script kills it after 2 seconds. On slow machines the window may flash visibly. |
| Currently commented out | The HideDesktopIcons block lives in the file but is commented out. Uncomment to hide desktop icons. |