Skip to content

Latest commit

 

History

History
242 lines (184 loc) · 17.2 KB

File metadata and controls

242 lines (184 loc) · 17.2 KB

Dev Configuration

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.

Usage

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

  • 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-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)

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.

Apps

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.

Theme and OS

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

File Explorer

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

Taskbar

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

Start, Search, Notifications

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

Services and features

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

Edge

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

Fonts

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.

Windows Terminal

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.

PowerShell profile

Resource Type What it does
ohMyPoshProfileSet Microsoft.DSC.Transitional/RunCommandOnSet Creates $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

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.

Known caveats

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.